Angular 2+使用DI与实例化模型

时间:2017-04-30 18:44:18

标签: javascript angular

我希望能够使用构造函数实例化模型,但仍然为该模型注入服务。

换句话说,我希望能够做到这样的事情:

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中看到的唯一方法。

问题:

  1. 这种策略不受欢迎吗?这不是“Angular方式”吗?
  2. 有没有更好的方法来做我想做的事情?我找到了一些事情,例如providers.useFactoryReflectiveInjector,但似乎都没有完成我的目标正在寻找。
  3. 感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

在我看来,你不会在角度方面做些坏事,而是在软件设计方面。看起来你混合了责任。不应该预订一个只持有图书数据的班级。执行api调用的类应该是某种存储库模式,它从book实例中获取id或其他数据。另请查看Solid

中的s

答案 1 :(得分:1)

我按如下方式解释你在做什么:

  • 您首先有一个页面通过http从远程服务器加载Books 致电
  • 一旦你在应用程序中有了你的图书清单,那么你就可以拥有 需要为特定的Book再次查询远程服务器获取更多数据

如果是这种情况,则必须使用2种方法构建服务(例如BookService):

  • getBookList(): Observable<Book[]>
  • getDetailsForBook(book: Book): Observable<any>(此方法返回的Observable的类型可以通过特定的输入更具体,这取决于应用程序的上下文)

BookService本身使用DI以标准Angular方式获取Angular Http客户端(即在其构造函数中引用Http)。

然后可以在DI中配置BookService并将其提供给需要使用它的所有组件(或服务)。

我希望这很清楚,可以提供帮助。