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: `
<div>This is child!!!</div>
`
})
export class VPChild{
constructor(
private service: MyService
){
this.service.testIfGetService('child');
}
}
这个组件注入了MyService
服务,调用MyService
的testIfGetService
方法,并传入child
表明这是在child组件调用的。
还有另外一个子组件,这个组件是用来放在父组件的模板(template)里面的:
// viewChild.component.ts
import { Component } from '@angular/core';
import { MyService } from './myService.service';
@Component({
selector: 'vp-viewchild',
template: `
<div>This is viewChild!!!</div>
`
})
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: `
<div>This is parent!!!</div>
<ng-content></ng-content>
<vp-viewchild></vp-viewchild>
`,
providers: [MyService]
})
export class VPParent{
constructor(
private service: MyService
){
this.service.testIfGetService('parent');
}
}
在父组件,用providers
注册MyService
,然后调用MyService
的testIfGetService
传入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: `
<div>This is parent!!!</div>
<ng-content></ng-content>
<vp-viewchild></vp-viewchild>
`,
viewProviders: [MyService] // <---
})
export class VPParent{
constructor(
private service: MyService
){
this.service.testIfGetService('parent');
}
}
这样修改之后,运行程序,发现报错了:
如果把contentChild注释掉,就像这样:
<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。
Angular:ViewProviders和Providers的区别的更多相关文章
- [Angular] Difference between Providers and ViewProviders
For example we have a component: class TodoList { private todos: Todo[] = []; add(todo: Todo) {} rem ...
- [Angular 2] Value Providers & @Inject
Dependecies aren’t always objects created by classes or factory functions. Sometimes, all we really ...
- [Angular 2] BYPASSING PROVIDERS IN ANGULAR 2
Artical --> BYPASSING PROVIDERS IN ANGULAR 2 Here trying to solve one problem: On the left hand s ...
- [Angular] Pipes as providers
In this example, we are going to see how to use Pipe as providers inject into component. We have the ...
- angular $observe() 和$watch的区别
1.$observe()是属性attributes的方法,只能在DOM属性的值发生变化时用,并且只用于directive内. 当需要监听一个包含变量的属性值时attr1="Name:{{na ...
- angular js jquery中post请求的一点小区别
这也是最近遇到的坑,还是之前那个项目,现在要实现登录功能. 背景:注册功能之前已经跑通了.前端用的是jquery后台是springMVC.鉴于注册和登录有些接口功能是类似的(比如注册确保邮箱是没有注册 ...
- angular学习—组件
组件: vue组件:xxx.vue react组件:xxx.js+xxx.css angular组件:xxx.ts+xxx.css+xxx.html angular的装饰器: @ngModule:an ...
- quora 中有关angular与emberjs的精彩辩论
原贴地址,要注册才能看,这里只有国人翻译的一部分内容 本文源自于Quora网站的一个问题,作者称最近一直在为一个新的Rails项目寻找一个JavaScript框架,通过筛选,最终纠结于Angular. ...
- Angular.js vs Ember.js
Angular.js 拥抱 HTML/CSS Misko Hevery(Angular.js的开发者之一)回答了这一问题,他的主要观点如下: 在HTML中加入太多逻辑不是好做法.Angular.js只 ...
随机推荐
- xcode archive灰色,无法打包的解决办法
问题如图: 解决办法:目前的运行配置是使用模拟器,改成“iOS Device”即可 step1: step2: 修改后archive选项变为黑色,可点击状态了
- 009-elasticsearch5.4.3【三】搜索概述-查询模型、分页、ES数据类型
一.概述 1.查询模型 搜索API允许用户执行搜索查询并返回与查询匹配的搜索匹配.它可以跨一个或多个索引以及跨一种或多种类型执行.可以使用查询Java API提供查询.搜索请求的主体是使用Search ...
- Delphi XE2 之 FireMonkey 入门(17) - 特效
刚打开 XE2 时, 就从 Tool Palette 窗口的 Effects 组中发现洋洋洒洒的六十多个特效... 每个特效分别对应一个类, 分别来自 FMX.Effects 和 FMX.Filter ...
- js面向对象程序设计之继承
在面向对象语言中继承分成两种:接口继承和实现继承.解释一下,接口继承只继承方法的签名,而实现继承则是继承实际的方法.但是ECMAScript中的函数没有签名所以无法进行接口继承,只能是实现实现继承.而 ...
- [Python3] 017 字典的内置方法
目录 1. Python3 中如何查看 dict() 的内置方法 2. 少废话,上例子 (1) 清理大师 clear() (2) 拷贝君 copy() (3) get(key, default=Non ...
- HDUSTOJ-1558 Flooring Tiles(反素数)
1558: Flooring Tiles 时间限制: 3 Sec 内存限制: 128 MB提交: 59 解决: 36[提交][状态][讨论版] 题目描述 You want to decorate ...
- 使用 js 修饰器封装 axios
修饰器 修饰器是一个 JavaScript 函数(建议是纯函数),它用于修改类属性/方法或类本身.修饰器提案正处于第二阶段,我们可以使用 babel-plugin-transform-decorato ...
- 关于 Python 程序的运行方面,有什么手段能提升性能?
1.使用多进程,充分利用机器的多核性能2.对于性能影响较大的部分代码,可以使用 C 或 C++编写3.对于 IO 阻塞造成的性能影响,可以使用 IO 多路复用来解决4.尽量使用 Python 的内建函 ...
- ECarts 的初步使用
ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等) ...
- 深入JavaScript之获取cookie以及删除cookie
cookie存在哪? 存在document.cookie中 ookie长啥样? cookie是一个字符串,长下面这样:“name=xxx; age=22;” 注意:分号后面有个空格,记住这一点,下面的 ...