我有这个EventsStorage typescript 类,它负责在ionic-storage(sqlite和indexedDB的包装器)中存储和检索Event对象。它自始至终都使用我的 Event 类。
我想将很多这样的逻辑重用于事件以外的其他东西,比如小部件。
我有 Ruby 背景,提取所有存储逻辑、设置一个实际上是类 Event 的 ruby var 并在任何使用 Event 的地方使用该 var 会相对简单。我可以在 typescript 中做类似的事情吗?是否有另一种机制可以让我将此类的大部分内容重用于其他内容,例如 Widget?
理想情况下,我的 EventsStorage 类变得非常轻量级,而且我不仅仅是包装对 this.some_storage_module.get_ids()
或 this.some_storage_module.insert_new_objs()
的调用-- 必须将其复制/粘贴到我需要的每个其他实例。
类似这样的事情:
export class EventsStorage { // extends BaseStorage (maybe??)
constructor(){
super(Event, 'events'); // or some small set of magical args
}
}
这是现有的类:
import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage';
import { Event } from '../classes/event';
// EventsStorage < EntityStorage
// - tracks local storage info
// - a key to an array of saved objects
// - a query() method that returns saved objects
@Injectable()
export class EventsStorage {
base_key: string;
ids_key: string;
constructor(
private storage: Storage
){
this.base_key = 'event';
this.ids_key = [this.base_key, 'ids'].join('_');
}
get_ids(): Promise<any>{
return this.storage.ready().then(() => {
return this.storage.get(this.ids_key).then((val) => {
if(val === null){
return [];
} else {
return val;
}
});
});
}
insert_new_objs(new_objs: any): Promise<any>{
return new_objs.reduce((prev: Promise<string>, cur: any): Promise<any> => {
return prev.then(() => {
return this.storage.set(cur._id, cur.event);
});
}, Promise.resolve()).then(() => {
console.log('saving event_ids');
return this.storage.set(this.ids_key, new_objs.map(obj => obj._id));
});
}
update(events: Event[]): Promise<any> {
let new_objs = events.map((event) => {
return {
_id: [this.base_key, event.id].join('_'),
event: event
};
});
return this.insert_new_objs(new_objs);
}
query(): Promise<Event[]>{
let events = [];
return this.get_ids().then((ids) => {
return ids.reduce((prev: Promise<string>, cur: string): Promise<any> => {
return prev.then(() => {
return this.get_id(cur).then((raw_event) => {
events = events.concat([raw_event as Event]);
return events;
});
});
}, Promise.resolve());
});
}
get_id(id: string): Promise<Event>{
return this.storage.get(id).then((raw_event) => {
return raw_event;
});
}
}
最佳答案
在我看来你想使用泛型。您基本上在要存储的所有内容之间定义了一些基本接口(interface),并且您的代码应该依赖于该接口(interface)。据我所知,在您的代码中仅使用 id
属性。
所以它看起来有点像这样
import { Event } from '...';
import { Widget } from '...';
interface HasId{
id: string;
}
class ItemsStorage<T extends HasId> {
....
get_id(id: string): Promise<T>{
...
}
}
const EventStorage = new ItemsStorage<Events>(storage);
const WidgetStorage = new ItemsStorage<Widget>(storage);
const ev = EventStorage.get_id('abc'); //type is Promise<Event>
const wd = WidgetStorage.get_id('def'); //type is Promise<Widget>
您可以阅读有关泛型的更多信息 here .
编辑: 1 - 关于子类化 - 通常不太可取。如果您的 ItemsStorage 类在处理事件与小部件时需要不同的行为,那么子类化就是您的解决方案。但是,如果每个类都有相同的行为,人们可能会称您的代码为泛型,并且使用泛型会更好。
关于javascript - 如何使此类在 typescript 中可重用?元编程?子类?注入(inject)模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42013379/