Angular2 Dart:将项目分成包不允许使用修改后的提供者重用基础组件

Angular2 Dart: Dividing a project in packages does not allow to reuse base components with modified providers

我有一个使用 Dart (1.24.2) 和 angular dart (3.1.0) 的大型应用程序。 我决定将应用程序分成两个包:第一个是基础层,第二个是真正的应用程序包。这个想法是为了能够在其他项目中重用基础层。 在基础层中,我使用了几个对应用程序来说是全局的并且被广泛使用的服务(提供者)。 现在,在应用层我需要为一些服务添加一些字段。 我遇到的问题是您不能使用使用修改过的服务的基础层组件。我收到的消息是:"EXCEPTION: No provider found for ." 我不能说这是错误,但它有助于创建 angular 模块。 一个例子。 我已经(从 Webstorm)生成了一个使用 Angular2 的示例应用程序:Todo 列表应用程序。 鉴于此,我对 "src/todo_list/todo_list_component.dart" 源代码进行了一些修改,删除了 TodoListService 提供程序。

  //providers: const [TodoListService],

并将声明移动到 AppComponent class:

import 'src/todo_list/todo_list_service.dart';


// AngularDart info: https://webdev.dartlang.org/angular
// Components info: https://webdev.dartlang.org/components

@Component(
  selector: 'my-app',
  styleUrls: const ['app_component.css'],
  templateUrl: 'app_component.html',
  directives: const [materialDirectives, TodoListComponent],
  providers: const [materialProviders, TodoListService],
)
class AppComponent {

这样,该服务对于 AppComponent 调用的所有组件都是全局的。

然后我生成了第二个项目,总是一个 TodoList 示例并进行了与之前相同的修改(全球化 TodoListService)。

现在,我在派生包中执行了以下操作: 添加了对基础层包的引用; 取消了 src/todo_list/todo_list_component.dart、.css 和 .html。 这是因为我要使用基础层封装TodoList组件。 向 TodoListService 添加了一个字段:

import 'package:angular2/core.dart';
import 'package:angular_inject_subclass_base/src/todo_list/todo_list_service.dart' as base;

/// Mock service emulating access to a to-do list stored on a server.
@Injectable()
class TodoListService extends base.TodoListService {

  String description;

}

最后一次修改,在AppComponent源码中,我修改了对基础层TodoListComponent的引用:

import 'package:angular_inject_subclass_base/src/todo_list/todo_list_component.dart';

尝试 运行 派生项目时出现以下错误:

(匿名函数)异常:未找到 TodoListService 的提供程序。堆栈跟踪:
0 _EmptyInjector.get(包:angular2/src/core/di/injector.dart:54:7)
1 _MapInjector.get(包:angular2/src/core/di/injector.dart:73:52)2 ReflectiveInjectorImpl._getByKeyDefault(包:angular2/src/core/di/reflective_injector.dart:816:18)
3 ReflectiveInjectorImpl._getByKey(包:angular2/src/core/di/reflective_injector.dart:782:14)
4 ReflectiveInjectorImpl.get(包:angular2/src/core/di/reflective_injector.dart:529:17)
5 AppView.injectorGet(包:angular2/src/core/linker/app_view.dart:236:37)
6调试AppView.injectorGet(包:angular2/src/debug/debug_app_view.dart:98:31)
7 ViewAppComponent0.build(包:angular_inject_subclass_derived/app_component.template.dart:90:71) 8 AppView.create(包:angular2/src/core/linker/app_view.dart:180:12)

还有其他方法吗? 是否可以在 Angular 中更改此行为,以便也可以注入提供程序的子 class 而不是原始提供程序?

您可以使用

提供子class
providers: const [
    materialProviders, 
    const Provider(base.TodoListService, useClass: TodoListService)
],

然后当某些 class 依赖于 base.TodoListService 时,Angular 将注入 subclass TodoListService ,它将与被调用的构造函数兼容,因为它是子class.

TodoListService 单独是 const Provider(TodoListService, useClass: TodoListService)

的缩写形式(可能会在 Angular 5 中停用)