【问题标题】:How to call code inside ngAfterViewInit again in angular 2如何在 Angular 2 中再次调用 ngAfterViewInit 中的代码
【发布时间】:2018-02-15 10:03:27
【问题描述】:

在我的 Angular 组件中,我有 ngAfterViewInit 方法,其中包含一些我想在视图初始化后执行的语句,因为它包含一些 DOM 操作。

我的问题是,当某些参数发生更改时,我想在ngAfterViewInit 中运行代码。

【问题讨论】:

  • 只需将代码移动到您从ngAfterViewInit 调用的另一个方法以及您想要的任何其他地方。
  • 如果组件未初始化,该代码会给我错误。这就是为什么我把它放在 ngAfterViewInit 里面。
  • 也许这个plunkr example helps
  • 请贴出导致错误的代码和错误信息。
  • @GünterZöchbauer 代码使用 d3 绘制图形。

标签: javascript angular typescript angularjs-directive


【解决方案1】:

您可以在构造函数中定义一个EventEmitter,在ngAfterViewInit() 函数中订阅它以更新这些值,在ngAfterViewInit() 函数中发出它,然后每次您想调用它时再次发出它在组件的后续区域。这是一个例子:

import { EventEmitter } from '@angular/core';

export class MyComponent implements AfterViewInit {
  public myEvent: EventEmitter<void>;
  
  public constructor() {
    this.myEvent = new EventEmitter<void>();
  }
  
  public ngAfterViewInit(): void {
    // This is how you call the function to do what you want to do with your DOM manipulations below. You can also call this exact function even from the HTML, if you wish to do so (see HTML example).
    this.myEvent.emit();
    
    this.myEvent.subscribe(
      () => {
        // Do whatever actions that you need to do here to perform your DOM manipulations.
      },
      (err: Error) => console.error(err);
    );
  }
  
  public emitMyEvent(): void {
    this.myEvent.emit();
  }
}
<my-component (click)="myEvent.emit()"></my-component>

<!-- or -->

<my-component (click)="emitMyEvent()"></my-component>

【讨论】:

    【解决方案2】:

    如果您想在每次更改时执行这些语句,最好将这些语句写在ngAfterViewChecked()。来自the docs

    在默认更改检测器完成检查组件视图的更改后调用的生命周期挂钩

    在默认更改检测器完成一个组件视图的更改检查周期后立即调用的回调方法。

    因此它将在每次后续更改时调用。

    更多信息也可以在Lifecycle Hooks#AfterView 文档中找到

    【讨论】:

      【解决方案3】:

      如果您的参数可以作为 Observable 使用,您可以在 ngAfterViewInitmethod 中订阅它。如果您的参数还不能作为 Observable 使用,我建议您查看 BehaviourSubject 类。有了这个,你可以控制 Observable 何时发出一个新值 + 当你订阅它时,它将被最后一个值触发

      【讨论】:

      • 感谢您的回答,因为我没有在 ngAfterViewInit() 中订阅我的 Observable(bcoz- 我在模板中使用异步管道直接呈现来自服务器的最新数据)所以我的模板没有得到更新结果。
      【解决方案4】:

      你在类体中声明普通类方法,然后在 ngAfterviewInit 的上下文中定义它们。 这是一个简单的用例示例:

      export class ViewtestComponent implements OnInit, AfterViewInit{
        @ViewChild('someElementMewantedToDoAction') elRef: ElementRef;
      
        constructor() { }
      
        ngOnInit(): void {
        }
      
        changeVal; 
      
        ngAfterViewInit() {
          this.changeVal= (useME) => {
            // some action
            this.elRef.nativeElement.innerText++;
          }
         }
      

      稍后,使用模板中的方法作为

      // Do Action=  Button value will increment 11, 12 13 ... on each button   click.
      
      <button class="button success" (click)="changeVal($emit)>10</button>
      

      【讨论】:

      • 在 ngAfterViewInit() 中使用函数声明的函数表达式效果很好。
      【解决方案5】:

      我通过实现OnChanges 解决了我的问题,并调用ngAfterviewInit 进行除第一次更改之外的更改。这样我将确保视图已初始化。顺便说一下,被改变的变量(changed_var)保存了DOM操作中使用的数据。

      ngOnChanges(changes: SimpleChanges){
          if(!changes.changed_var.isFirstChange()){
              this.ngAfterViewInit();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2017-12-10
        • 2017-10-21
        • 2020-09-17
        • 2018-05-24
        • 1970-01-01
        • 1970-01-01
        • 2018-12-14
        • 2019-03-08
        • 2017-11-22
        相关资源
        最近更新 更多