PHP8.1.21版本已发布
vue8.1.21版本已发布
jquery8.1.21版本已发布

在Angular里ViewProviders和Providers的区别

php中世界最好的语言
php中世界最好的语言 原创
2018-03-19 16:52:22 4057浏览

这次给大家带来在Angular里ViewProviders和Providers的区别,在Angular里使用ViewProviders和Providers的注意事项有哪些,下面就是实战案例,一起来看一下。

在Angular中使用依赖注入(DI)的时候,我们一般会使用providers。其实要做同样的事我们还有另外一个选择:viewProviders

viewProviders允许我们定义只对组件的view可见的provider。下面我们用例子详细的说明这一点。
假设我们有一个简单的服务:

// myService.service.ts
import { Injectable } from '@angular/core';
@Injectable()
export class MyService{
  testIfGetService(where){
    console.log('Got My Service in ' + where);
  }
}

这个服务很简单,只需要打印出在哪里调用了该服务。
然后有一个子组件,是用来投射到父组件里面的(等会将会看到):

// 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');
  }
}

这个组件注入了MyService服务,调用MyServicetestIfGetService方法,并传入child表明这是在child组件调用的。
还有另外一个子组件,这个组件是用来放在父组件的模板(template)里面的:

// 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');
  }
}

这里同样注入MyService服务,调用MyService服务的testIfGetService方法,并传入viewChild
最后是父组件:

// 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');
  }
}

在父组件,用providers注册MyService,然后调用MyServicetestIfGetService传入parent
然后就像这样使用父组件:

<vp-parent>
  <vp-child></vp-child></vp-parent>

运行程序,控制台打印出了结果:

一切就像预期那样!!
然后,我们用viewProviders代替providers注册MyService,看看会发生什么:

// 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] // <p style="text-align: left;">这样修改之后,运行程序,发现报错了:<br><img src="https://img.php.cn/upload/article/000/061/021/0103034ea60f5ad3e6ee3b8a0596b325-1.png"></p><p  style="max-width:90%">如果把contentChild<a href="http://www.php.cn/code/8105.html" target="_blank">注释</a>掉,就像这样:</p><pre class="brush:php;toolbar:false"><vp-parent>
  <!-- <vp-child></vp-child> -->
</vp-parent>

是不会报错的:

这就说明,在父组件用viewProviders注册的provider,对contentChildren是不可见的。而使用providers注册的provider,对viewChildren和contentChildren都可见!
补充说明:组件会逐级向上寻找provider,直到找到为止,否则就会抛出错误。就像这里:

<vp-parent>
  <vp-child></vp-child></vp-parent>

vp-child往上找MyService的provider,结果在vp-parent找到了。但是在用viewProviders的时候,vp-child往上找,也就是到vp-parent,结果没找到,然后又去找vp-parent的父级,还是没找到(因为在这个例子里,我们只在vp-parent注册了MyService),然后又继续往上找……如此找到边界也没找到,所以抛出了一个错误。如果你不希望这样,可以使用@Host做出限制,就像这样:

constructor(
    @Host() private service: MyService
){}

关于@Host()本文不作展开,有兴趣可以自行google。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Vue.js的表单输入绑定

React中有哪些类定义组件

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。