美文网首页
13Angular组件投影

13Angular组件投影

作者: learninginto | 来源:发表于2020-12-25 10:08 被阅读0次

    用法类似于ViewChild,获取投影中的组件、指令和dom元素,类似于vue中的具名插槽和匿名插槽

    import { Component, Input, TemplateRef } from '@angular/core';
    @Component({
      selector: 'app-shadow',
      template: `
                <div class="shadow">
                  <div class="head">
                    <ng-content select=".head"></ng-content>
                  </div>
                  <div class="body">
                    <ng-content select="[attr]"></ng-content>
                    <ng-content select="article"></ng-content>
                    <ng-content></ng-content>
                  </div>
                  <div class="foot">
                    <ng-content select=".foot"></ng-content>
                  </div>
                </div>`
    })
    export class ShadowComponent  {}
    
    • 调用ShadowComponent
    import { Component, Input } from '@angular/core';
    @Component({
      selector: 'app-root',
      template: `
                <app-shadow [visible]="true">
                  <div class="head">这是head的投影</div>
                  <div attr>这是attr的投影内容</div>
                  <article>这是article的投影内容</article>
                  <b style="color: #007bff">这是默认的投影内容</b>
                  <div class="foot">这是foot的投影</div>
                </app-shadow>
              `
    })
    export class AppComponent  {}
    
    获取投影中的组件
    • ContentChild
    import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
    
    @Component({
      selector: 'app-content-child-panel',
      templateUrl: './content-child-panel.component.html'
    })
    export class ContentChildPanelComponent implements OnInit {
    
      constructor() { }
    
      ngOnInit(): void {}
    
      alert() {
        alert('aa');
      }
    }
    
    @Component({
      selector: 'app-content-child',
      template: `
          <div class="content-child-box">
            <h2>这是content child组件</h2>
            <div class="head" style="border: 1px solid; margin: 10px 0;">
              <ng-content select=".head"></ng-content>
            </div>
            <ng-content></ng-content>
          </div>
     `,
      styles: []
    })
    export class ContentChildComponent implements AfterViewInit {
      // 无法获取dom元素
      // @ContentChild('.head', { static: true }) private headEl: ElementRef;
      // @ContentChild('list', { static: true }) private listEl: ElementRef;
      @ContentChild(ContentChildPanelComponent, { static: true }) private panel: ContentChildPanelComponent;
      constructor() { }
    
      ngAfterViewInit(): void {
        this.panel.alert();
      }
    
    }
    
    • 调用ContentChildComponent
    <app-content-child>
      <div class="head">
        这是头部
      </div>
      <app-content-child-panel></app-content-child-panel>
      <ul #list>
        <li>aaa</li>
        <li>bbb</li>
      </ul>
    </app-content-child>
    
    • ContentChildren

    用法类似ViewChildren, 批量获取投影中到组件或指令

    <app-content-child>
      <div class="head">
        这是头部
      <app-content-child-panel></app-content-child-panel>
      </div>
      <app-content-child-panel></app-content-child-panel>
      <app-content-child-panel></app-content-child-panel>
      <ul #list>
        <li>aaa</li>
        <li>bbb</li>
      </ul>
    </app-content-child>
    
    export class ContentChildComponent implements AfterViewInit {
      @ContentChildren(ContentChildPanelComponent) private panels: QueryList<ContentChildPanelComponent>;
      constructor() { }
    
      ngAfterViewInit(): void {
        console.log(this.panels); // 只有两个结果
      }
    
    }
    

    这里只能拿到两个panels,默认只寻找直属的panel 而.head里的panel组件嵌套了一层div,并非直属

    想要拿到所有层级的panel组件,需要开启descendants属性

    @ContentChildren(ContentChildPanelComponent, { descendants: true }) private panels: QueryList;
    

    相关文章

      网友评论

          本文标题:13Angular组件投影

          本文链接:https://www.haomeiwen.com/subject/opsbnktx.html