2017-08-29 2 views
1

J'ai une grande application en utilisant Dart (1.24.2) et dart angulaire (3.1.0). J'ai décidé de diviser l'application en deux paquets: le premier est une couche de base et le second est le vrai paquet d'application. L'idée est de pouvoir réutiliser la couche de fondation dans d'autres projets. Dans la couche de base j'utilise plusieurs services (fournisseurs) qui sont globaux à l'application et sont largement utilisés. Maintenant, dans la couche application, j'avais besoin d'ajouter des champs à certains services. Le problème que j'avais, c'est que vous ne pouvez pas utiliser un composant de la couche de fondation qui utilise un service modifié. Le message que je reçois est: "EXCEPTION: Aucun fournisseur trouvé pour". Je ne peux pas dire que c'est un bug, mais cela serait utile pour créer des modules angulaires. Un exemple. J'ai généré (à partir de Webstorm) un exemple d'application utilisant Angular2: L'application de liste Todo. Par conséquent, j'ai modifié un peu la source "src/todo_list/todo_list_component.dart" supprimant le fournisseur TodoListService.Angular2 Dart: La division d'un projet en paquets ne permet pas de réutiliser les composants de base avec les fournisseurs modifiés

//providers: const [TodoListService], 

et déplacer la déclaration dans la classe AppComponent:

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 { 

De cette façon, le service est global à tous les composants appellent par AppComponent.

Puis j'ai généré un deuxième projet, toujours un exemple TodoList et fait les mêmes modifications que précédemment (globalisation du TodoListService).

Maintenant, dans le paquetage dérivé, j'ai fait ce qui suit: Ajout d'une référence au paquet de couches de fondation; Annulé src/todo_list/todo_list_component.dart, .css et .html. Ceci parce que je veux utiliser le composant TodoList du paquet de la couche de fondation. Ajout d'un champ à l'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; 

} 

Dernière modification, dans la source AppComponent, j'ai changé la référence à la TodoListComponent de la couche de fondation:

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

Essayer de lancer le projet dérivé je suis arrivé l'erreur suivante:

(fonction anonyme) EXCEPTION: Aucun fournisseur trouvé pour TodoListService. STACKTRACE:
0 _EmptyInjector.get (paquet: angular2/src/core/di/injector.dart: 54: 7)
1 _MapInjector.get (paquet: angular2/src/core/di/injector.dart: 73: 52) 2 ReflectiveInjectorImpl._getByKeyDefault (package: angular2/src/noyau/di/reflective_injector.dart: 816: 18)
3 ReflectiveInjectorImpl._getByKey (package: angular2/src/core/di/reflective_injector.dart: 782: 14)
4 ReflectiveInjectorImpl.get (package: angular2/src/noyau/di/réflective_injector.dart: 529: 17)
5 AppView.injectorGet (package: angular2/src/core/linker/app_view.dart: 236: 37)
6 DebugAppView.injectorGet (package: angular2/src/debug/debug_app_view.dart: 98: 31)
7 ViewAppComponent0.build (package: angular_inject_subclass_derived/app_component.template.dart: 90: 71) 8 AppView.create (package: angular2/src/core/linker/app_view.dart: 180: 12)

Existe-t-il un autre moyen de le faire? Est-il possible de modifier ce comportement dans Angular afin qu'une sous-classe du fournisseur puisse également être injectée à la place de l'originale?

Répondre

2

Vous pouvez fournir des sous-classes à l'aide

providers: const [ 
    materialProviders, 
    const Provider(base.TodoListService, useClass: TodoListService) 
], 

alors quand une classe dépend base.TodoListService, angulaire injectera la sous-classe TodoListService qui sera compatible avec le constructeur appelé parce qu'il est une sous-classe.

TodoListService seul est une forme courte (qui sera probablement interrompu à angulaire 5) pour const Provider(TodoListService, useClass: TodoListService)