代码之家  ›  专栏  ›  技术社区  ›  Andrew

Angular@ViewChild它在做什么

  •  0
  • Andrew  · 技术社区  · 5 年前

    我一直在阅读下面链接中提供的Angular的动态组件加载部分,我的小脑袋看起来非常复杂和困惑,很难理解所有的语法和名称。

    https://angular.io/guide/dynamic-component-loader

    我的问题是@ViewChild是做什么的?有角度的文件规定:

    配置视图查询的属性装饰器。

    但这并不能理解它的作用“什么是视图查询,这意味着什么”?或者我们为什么要使用它。

    后来我在谷歌上搜索了一个视图查询,它给出了:

    视图查询是对中的子元素的请求引用 包含元素元数据的组件视图

    但在上面的url中显示的下面的代码中,我再次不知道为什么或这对我来说是什么。

    也许这一部分应该在指令之后,因为我一定遗漏了什么。

    当它在loadComponent()函数中调用它时,adHost是一个似乎是空的指令(其中没有代码)。如果你看下面的代码,什么是viewContainerRef,viewContainerRef是我的实际子组件吗?

    const viewContainerRef = this.adHost.viewContainerRef;
    viewContainerRef.clear();
    

    有人知道有什么网站对此有简单易懂的用途吗?

    ad-banner.component.ts如下所示:

    import { Component, OnInit, OnDestroy, Input, ViewChild, ComponentFactoryResolver} from '@angular/core';
    import { AdItem } from '../ad-item';
    import { AdDirective } from '../ad.directive';
    import { AdComponent } from '../AdComponent';
    
    @Component({
      selector: 'app-ad-banner',
      templateUrl: './ad-banner.component.html'
    })
    export class AdBannerComponent implements OnInit, OnDestroy {
      
      @Input() ads: AdItem[] = [];
      currentAdIndex = -1;
    
      @ViewChild(AdDirective, {static: true}) adHost!: AdDirective;
      interval: any;
    
      constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
    
      ngOnInit(): void {
        this.loadComponent();
        this.getAds();
      }
      
      ngOnDestroy(): void {
        clearInterval(this.interval);
      }
    
      loadComponent() {
        this.currentAdIndex =(this.currentAdIndex + 1) % this.ads.length;
        const adItem = this.ads[this.currentAdIndex];
    
        const componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component);
    
        const viewContainerRef = this.adHost.viewContainerRef;
        viewContainerRef.clear();
    
        const componentRef = viewContainerRef.createComponent<AdComponent>(componentFactory);
        componentRef.instance.data = adItem.data;
      }
    
      getAds() {
        this.interval = setInterval(() => {
          this.loadComponent();
        }, 3000);
      }
    
    }
    

    add-banner.component.html如下所示:

    <div class="add-banner-example">
        <h3>Advertisements</h3>
        <ng-template adHost></ng-template>
    </div>
    

    ad.directive.ts看起来是这样的:

    import { Directive, ViewContainerRef } from "@angular/core";
    
    @Directive({
        selector: '[adHost]'
    })
    export class AdDirective {
        constructor(public viewContainerRef: ViewContainerRef) {
            
        }
    }
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   Dharman vijay    5 年前

    我相信Angular University博客上的这篇文章可以帮助你: https://blog.angular-university.io/angular-viewchild/ 。它以一种易于理解的方式得到了充分的解释。

    但是,不出所料,ViewChild()就像一个DOM选择器,但具有一些有趣的功能。正如您将在上面的文章中了解到的,它可以选择本地DOM元素(例如,一个简单的DIV)或Angular Feature的实例,如组件或指令,这使您可以完全访问其属性和方法。

    这就是您的代码所做的:它选择应用ViewChild()的指令的实例:

    @ViewChild(AdDirective, {static: true}) adHost!: AdDirective;
    

    在这种情况下,您可以通过实现ngAfterViewInit生命周期挂钩来检查adHost实例:

    export class AdBannerComponent implements OnInit, OnDestroy, OnAfterViewInit {
      
      // .. all your code 
      
      ngAfterViewInit() {
        console.log(adHost);
      }
      
      // ... all your code (continued...)
    }
    

    通过这样做,你会发现这是多么强大。

    推荐文章