Angular2中ViewChild与ContentChild的区别

by wilhan.tian 欢迎转载,转载请注明出处


ViewChild

官方文档翻译

先来看看官方解释

  • 声明一个对子元素的引用。
  • ViewChild需要一个参数来选择元素。
  • 如果参数是一个类型,一个指令或一个类型的组件将被绑定。
  • 如果参数是一个字符串,字符串被解释为一个选择器。也就是一个元素包含模板变量(如 #child)。
  • 在任何情况下,如果找到多个元素,那么只返回第一个。
  • 这个子元素将在ngAfterViewInit()回调前被赋值。

笔者英语已经还给体育老师,各位看官将就着,自己理解一下。

不理解吗?

不理解吗?好吧,怪我,我用最通俗的东北话大概讲解下。

  • ViewChild就是选择元素用的。
  • 你不告诉它选择什么元素,它肯定不知道啊!所以你得给一个类型。
  • ViewChild这个兄弟还算讲究,你不告诉它类型可以,那就给他一个模板变量名。(下面会解释)
  • 如果这位仁兄找到了好多元素,那么它只会返回第一个找到的元素。
  • ViewChild会在ngAfterViewInit()回调函数之前做完工作,也就是说你不能在构造函数中使用这个元素。

更通俗一些

下面我将用程序员最直接的方式,帮助大家理解:

import {Component, ViewChild, AfterViewInit} from '@angular/core';

@Component({
    selector: 'my-com',
    template: '<button>我是一个按钮</button>'
})
export class MyCom{
}

@Component({
    template: '<my-com #myCom></my-com>'
    directives: [MyCom]
})
export class MyPage implements AfterViewInit{
    @ViewChild(MyCom) myComA;
    @ViewChild('myCom') myComB; 

    public constructor(){
        console.log(this.myComA);//undefined
        console.log(this.myComB);//undefined
    }

    public ngAfterViewInit(){
        console.log(this.myComA);//输出MyCom对象
        console.log(this.myComB);//输出MyCom对象
        console.log(this.myComA == this.myComB);//true
    }
}

好了,估计你已经知道基本的使用方式了

  • @ViewChild(MyCom) 可以获取到页面中的MyCom类型的组件
  • @ViewChild('myCom') 可以获取到被标记为#myCom的组件

ContentChild

点击这里查看官方解释

官方文档翻译

  • 查询一个内容。
  • 内容查询结果将在ngAfterContentInit()回调前完成

不是我偷懒没翻译全,官方就这两句话。这尼玛是甲骨文啊?什么叫查询一个内容

好在凭借我多年的学习和吹牛逼经验,在stackoverflow同志网站上找到了相关问题和解答

理解ContentChild

补充ViewChildren

@ViewChildren@ViewChild实际上没什么区别,从名字上很容易理解,一个获取一堆子元素,一个获取一个子元素。

  • @ViewChild(MyCom) 返回的是一个MyCom变量
  • @ViewChildren(MyCom) 返回的是一个QueryList<MyCom>

为什么突然蹦出个ViewChildren?因为下面老外使用它来解释的

老外的解释

stackoverflow上某老外这样解释

The difference between @ViewChildren and @ContentChildren is that @ViewChildren look for elements in Shadow DOM while @ContentChildren look for them in Light DOM.

我在用中文翻译下哈

@ViewChildren@ContentChildren之间的区别在于,@ViewChildren用于Shadow DOM,而@ContentChildren用于Light DOM

卧槽,Shadow DOM是什么?Light DOM又是什么? 这里有准确的答案

不完全解答

咦?如果你的基础较好的话,把ContentChildren这个两个单词分开,content-children好像似曾相识的感觉。想起没?ng-content

笔者理解: ContentChild用来获取<ng-content></ng-content>中的元素

我们写个伪代码实践下:

import {Component, ViewChild, ContentChild} from '@angular/core';

/// 儿子组件
@Component({
    selector: 'son-com',
    template: '<h1>im text</h1>',
    directives: [MyCom]
})
export class SonCom{
}

/// 爸爸组件
@Component({
    selector: 'father-com',
    template: '
        <son-com></son-com>
        <ng-content></ng-content>
    ',
    directives: [SonCom]
})
export class FatherCom implements AfterViewInit{
    @ViewChild(SonCom) viewCom;
    @ContentChild(SonCom) contentCom;

    public ngAfterViewInit(){
        console.log(this.viewCom);
        console.log(this.contentCom);
    }
}

最终输出:

<father-com>
    <h1>im text</h1>
    <h1>im text</h1>
</father-com>

然后我们调试后发现,this.viewCom等于第一行<h1/>this.contentView等于第二行<h1/>

这也证实了我的理解。

完结

欢迎拍砖


参考文献

Switching to Angular 2


  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值