[Angular] Difference between Providers and ViewProviders
For example we have a component:
class TodoList { private todos: Todo[] = []; add(todo: Todo) {} remove(todo: Todo) {} set(todo: Todo, index: number) {} get(index: number) {} getAll() {} } @Component({ // ... viewProviders: [TodoList] // ... }) class TodoAppComponent { constructor(private todos: TodoList) {} // ... }
For TodoAppComponent, we make 'TodoList' as 'viewProviders'.
And inside TodoAppComponent, we have TodoInputComponent & TodoComponent as view children, and AppFooterComponent as content child:
@Component({ selector: 'todo-app', template: ` <section> Add todo: <todo-input (todo)="addTodo($event)"></todo-input> </section> <section> <h4 *ngIf="todos.getAll().length">Todo list</h4> <todo *ngFor="let todo of todos.getAll()" [todo]="todo"> </todo> </section> <ng-content select="app-footer"></ng-content> ` })
So now, if we want to inject TodoList into TodoInputComponent and TodoComponent, that's fine. But once we try to inject TodoList service into FooterComponent, it will show the error:
ORIGINAL EXCEPTION: No provider for TodoList!
This is because when we use 'viewProviders' we can only inject service into component and its view children. Content Children (passed in by ng-content) cannot be injected.
When to use viewProviders
?
Why would I use viewProviders
, if such providers are not accessible by the content children of the component? Suppose you’re developing a third-part library, which internally uses some services. These services are part of the private API of the library and you don’t want to expose them to the users. If such private dependencies are registered with providers
and the user passes content children to any of the components exported by the public API of your library, she will get access to them. However, if you use viewProviders
, the providers will not be accessible from the outside.
相关文章
- [ngx-formly] Dynamically hide Form Controls with Angular Formly
- [Angular] @ViewChild read custom directive and exportAs
- [Angular] Remove divs to Preserve Style and Layout with ng-container in Angular
- [Angular] Use Angular’s @HostBinding and :host(...) to add styling to the component itself
- [Angular] Testing @Input and @Output bindings
- [Angular Unit Testing] Shallow Pipe Testing
- [Angular] Updating and resetting FormGroups and FormControls
- [Angular] @ViewChild and template #refs to get Element Ref
- [Angular] Difference between ngAfterViewInit and ngAfterContentInit
- [Angular] Difference between ViewChild and ContentChild
- [Angular2 Animation] Delay and Ease Angular 2 Animations
- [Angular 2] Generate and Render Angular 2 Template Elements in a Component
- [AngularJS] Angular 1.5 multiple transclude
- [AngularJS] Consistency between ui-router states and Angular directives
- [Angular] Reactive Forms Multi-field Custom Validation
- [Angular & Unit Testing] Testing Component with Store
- [Angular] Difference between ViewChild and ContentChild
- [Angular Testing] Unit Testing -- Test component and service.
- [Angular 2] Generate and Render Angular 2 Template Elements in a Component
- [Angular 2] Directive intro and exportAs
- [AngularJS] Consistency between ui-router states and Angular directives
- Angular @NgModule providers里multi等于true在源代码里如何体现的
- Angular单元测试框架里API toHaveBeenCalledTimes的工作原理
- Angular 服务器端渲染的学习笔记(二)
- Angular jasmine spied Method toHaveBeenCalled的执行原理