【问题标题】:Angular @ViewChild What is it doingAngular @ViewChild 它在做什么
【发布时间】:2023-03-26 06:36:02
【问题描述】:

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

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

我的问题是@ViewChild 做什么?角度文档指出:

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

但这并没有让人理解它的作用“什么是视图查询,这是什么意思”?或者我们为什么使用它。

我后来用谷歌搜索了什么是视图查询:

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

但是,在上面的网址中显示的代码中,我真的不知道为什么或这对我做了什么。

也许这部分应该在指令之后,因为我必须遗漏一些东西。

当它在 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.comoponent.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) {
        
    }
}

【问题讨论】:

    标签: angular


    【解决方案1】:

    我相信 Angular 大学博客上的这篇文章可以帮助到你:https://blog.angular-university.io/angular-viewchild/。它以易于理解的方式进行了全面解释。

    但是,可以预料,ViewChild() 就像一个 DOM 选择器,但是,具有一些有趣的功能。正如您将在上面的帖子中了解的那样,它可以选择原生 DOM 元素(例如,简单的 DIV)或 Angular 功能的实例,如组件或指令,这使您可以完全访问其属性和方法。

    这就是您的代码正在做的事情:它正在选择应用 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...)
    }
    

    通过这样做,您将看到它的强大功能。

    【讨论】:

    • 谢谢 我会读一读,应该增加知识。我所遵循的示例遗漏了很多东西,主要是 app.module.ts 文件中的组件和指令以及 entryComponents 的注册。这个链接也帮助我让它工作了stackoverflow.com/questions/48330760/…
    猜你喜欢
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 2016-06-21
    • 2021-10-04
    • 2019-06-20
    • 2015-12-31
    • 2016-08-05
    • 2010-09-20
    相关资源
    最近更新 更多