Home > Article > Web Front-end > The difference between ViewProviders and Providers in Angular
This time I will bring you the difference between ViewProviders and Providers in Angular. What are the precautions for using ViewProviders and Providers in Angular? The following is a practical case, let's take a look.
When usingDependency Injection (DI) in Angular, we generally use providers. In fact, we have another option to do the same thing:
viewProviders.
viewProvidersAllows us to define providers that are only visible to the component's view. Below we use examples to illustrate this point in detail.
Suppose we have a simple service:
// myService.service.ts import { Injectable } from '@angular/core'; @Injectable() export class MyService{ testIfGetService(where){ console.log('Got My Service in ' + where); } }This service is very simple, just print out where the service is called.
Then there is a child component, which is used to project into the parent component (you will see it later):
// child.component.ts import { Component } from '@angular/core'; import { MyService } from './myService.service'; @Component({ selector: 'vp-child', template: ` <p>This is child!!!</p> ` }) export class VPChild{ constructor( private service: MyService ){ this.service.testIfGetService('child'); } }This component injects the
MyService service and calls
##testIfGetService method of #MyService
, and passing in child
indicates that this is called in the child component. There is another sub-component, which is used to be placed in the template of the parent component:
// viewChild.component.ts import { Component } from '@angular/core'; import { MyService } from './myService.service'; @Component({ selector: 'vp-viewchild', template: ` <p>This is viewChild!!!</p> ` }) export class ViewVPChild{ constructor( private service: MyService ){ this.service.testIfGetService('viewChild'); } }
service and call The
testIfGetService method of the MyService
service and pass in viewChild
. Finally, the parent component:
// parent.component.ts import { Component } from '@angular/core'; import { MyService } from './myService.service'; @Component({ selector: 'vp-parent', template: ` <p>This is parent!!!</p> <ng-content></ng-content> <vp-viewchild></vp-viewchild> `, providers: [MyService] }) export class VPParent{ constructor( private service: MyService ){ this.service.testIfGetService('parent'); } }
with providers
, and then call testIfGetService of
MyService
Incoming parent
. Then use the parent component like this:
<vp-parent> <vp-child></vp-child> </vp-parent>
Everything is as expected! !
viewProviders
instead of providers
to register MyService
and see what happens: <pre class="brush:php;toolbar:false">// parent.component.ts
import { Component } from '@angular/core';
import { MyService } from './myService.service';
@Component({
selector: 'vp-parent',
template: `
<p>This is parent!!!</p>
<ng-content></ng-content>
<vp-viewchild></vp-viewchild>
`,
viewProviders: [MyService] // <---
})
export class VPParent{
constructor(
private service: MyService
){
this.service.testIfGetService('parent');
}
}</pre>
After this modification, run the program , and found that an error was reported:
If the contentChild
is removed, like this: <vp-parent>
<!-- <vp-child></vp-child> -->
</vp-parent>
will not report an error:
This means that the provider registered with
in the parent component is not visible to contentChildren. The provider registered using providers
is visible to both viewChildren and contentChildren! Additional explanation: The component will search for the provider step by step until it is found, otherwise an error will be thrown. Just like here:
<vp-parent> <vp-child></vp-child> </vp-parent>
went up to find the provider of MyService
, and found it in vp-parent
. But when using viewProviders
, vp-child
looks up, that is, to vp-parent
, but it is not found, and then goes to The parent of vp-parent
was still not found (because in this example, we only registered MyService
at vp-parent
), and then continued to look up... ...so the boundary was not found, so an error was thrown. If you don't want this, you can use @Host
to make restrictions, like this: <pre class="brush:php;toolbar:false">constructor(
@Host() private service: MyService
){}</pre>
This article will not expand on @Host(). If you are interested, you can google it yourself.
I believe you have mastered the method after reading the case in this article. For more exciting information, please pay attention to other related articles on the php Chinese website!
Recommended reading:
Vue.js form input bindingWhat class definition components are there in ReactThe above is the detailed content of The difference between ViewProviders and Providers in Angular. For more information, please follow other related articles on the PHP Chinese website!