我希望能够使用构造函数实例化模型,但仍然为该模型注入服务。
换句话说,我希望能够做到这样的事情:
var book = new Book({ id: 5 }); // creates instance, sets id = 5
book.makeHttpCall(); // makes an API call with Angular's http service
为了实现这一点,我有一个“工厂”,它使用标准依赖注入来获取http
服务。该工厂有一种方法,例如, make()
创建模型的实例。然后它引用它注入的http
服务,并将其分配给模型内的变量。
在代码中,以书籍为例:
使用此设置的服务:
@Injectable()
export class LibraryService {
constructor(
private http: Http,
private bookFactory: BookFactory
) {}
getBook(): Observable<BookModel> {
return this.http.get('http://localhost:3000/book/1')
.map((res) => {
return this.bookFactory.make(res.json().data)
});
}
}
工厂创建模型,并为他们提供http
服务:
@Injectable()
export class BookFactory {
constructor(public http: Http) {}
make(def): BookModel {
let book = new BookModel(def);
book.di = {
http: this.http
};
return book;
}
}
现在可以使用http
中的this.di.http
服务的图书模型:
export class BookModel {
di: any;
constructor(private def: object) {}
makeHttpCall() {
this.di.http.get(...)
...
}
}
我的作品。但它似乎非常hacky。好像我正在做一些非常违背“角度做事”的事情。在AngularJS(1.x)中,我使用普通的Angular工厂实现了这一点,一切都很顺利。但这似乎是我在Angular 2中看到的唯一方法。
问题:
providers.useFactory
和ReflectiveInjector
,但似乎都没有完成我的目标正在寻找。感谢任何帮助。
答案 0 :(得分:1)
在我看来,你不会在角度方面做些坏事,而是在软件设计方面。看起来你混合了责任。不应该预订一个只持有图书数据的班级。执行api调用的类应该是某种存储库模式,它从book实例中获取id或其他数据。另请查看Solid
中的s答案 1 :(得分:1)
我按如下方式解释你在做什么:
如果是这种情况,则必须使用2种方法构建服务(例如BookService
):
getBookList(): Observable<Book[]>
getDetailsForBook(book: Book): Observable<any>
(此方法返回的Observable的类型可以通过特定的输入更具体,这取决于应用程序的上下文) BookService
本身使用DI以标准Angular方式获取Angular Http
客户端(即在其构造函数中引用Http
)。
然后可以在DI中配置BookService并将其提供给需要使用它的所有组件(或服务)。
我希望这很清楚,可以提供帮助。