angular - 当我想明确清除未定义的属性 'viewContainerRef' 时,无法读取它

标签 angular typescript angular2-directives

有一种情况,我想在单击按钮时清除“viewContainer”,但它显示错误

ERROR TypeError: Cannot read property 'viewContainer' of undefined

请检查附加代码以便更好地理解。

注意:就我而言,您会看到,我在 document.body 上添加了点击事件,并将指令名称保留为 [ngIf](我知道这一点不是剧透)。

此外,我尝试在我的点击监听器中设置 this.ngIf = false; 但也会生成相同的错误。

"ERROR TypeError: Cannot set property 'ngIf' of undefined"

提前致谢。

app.component.ts

import { Component, TemplateRef, Directive, ViewContainerRef, Input, ElementRef, Renderer, ViewChild, ViewChildren, HostListener } from '@angular/core';


@Component({
  selector: 'my-app',
  template: `
<div *ngIf="val">
  Hello cpIf Directive.
</div>
  `,
  styles: [`h1 { font-family: Lato; }`]
})
export class AppComponent {

  val: boolean = true;

}


@Directive({
  selector: '[ngIf]'
})
export class CpIfDirective {
  constructor(private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
    private renderer: Renderer) {
    //this.viewContainer.createEmbeddedView(this.templateRef);
  }

  ngAfterViewInit() {
    //this.viewContainer.createEmbeddedView(this.templateRef);
    this.renderer.listen(document.body, 'click', this.clearView);
  }


  @Input() set ngIf(condition: boolean) {
    if (condition) {
      this.viewContainer.createEmbeddedView(this.templateRef);

    } else {
      this.viewContainer.clear();
    }
  }

  clearView(event: any) {
    this.viewContainer.clear();
    //this.ngIf = false;
  }

} 

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { HelloComponent, CpIfDirective } from './hello.component';

@NgModule({
  imports: [BrowserModule, FormsModule, ReactiveFormsModule],
  declarations: [AppComponent, HelloComponent, CpIfDirective],
  bootstrap: [AppComponent]
})
export class AppModule { }

最佳答案

您只是无法在 clearView 中访问this

使用这个:

this.renderer.listen(document.body, 'click', (event) => {
  // Do something with 'event'
   this.viewContainer.clear();
})

您没有将此引用传递给该 clearView 函数

Demo

或者像这样将容器引用传递给clearView

this.renderer.listen(document.body, 'click', (event) => {
      // Do something with 'event'
      this.clearView(event, this.viewContainer)
})


clearView(event: any, element) {    
    element.clear();
    //this.ngIf = false;
}

哦,是的,最重要的是,箭头函数无需更改任何内容即可工作,抱歉我之前没有考虑到这一点:)

An arrow function does not create its own this context, so this has its original meaning from the enclosing context.

  clearView = (event: any) => {    
    this.viewContainer.clear();
    //this.ngIf = false;
  }

Ref

关于angular - 当我想明确清除未定义的属性 'viewContainerRef' 时,无法读取它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53955825/

相关文章:

json - 不能在 *ngFor : angular2 中使用 *ngIF

javascript - 如何在 Angular 中将输入值作为参数传递给路由器

html - HTML不同的按钮样式-像齿轮一样

javascript - Angular 2 中的绑定(bind)数据

angular - 如何将加载指示器或 "spinner"添加到剑道 Angular 2 网格?

html - 如何以 Angular 解析嵌套的json

javascript - 我不知道 typescript 中的返回类型

typescript - 带有 i18next-node-fs-backend 的 i18next 显示键而不是字符串

javascript - 如何使用模型驱动/ react 形式修改指令中的输入值

Angular 2 将参数传递给构造函数抛出 DI 异常