【问题标题】:Cannot read property 'viewContainerRef' of undefined when I want to clear it explicitly当我想明确清除它时无法读取未定义的属性“viewContainerRef”
【发布时间】:2018-12-28 08:50:11
【问题描述】:

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

错误类型错误:无法读取未定义的属性“viewContainer”

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

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

另外,我尝试在单击的侦听器中设置this.ngIf = false;,但这也会产生相同的错误。

“错误类型错误:无法设置未定义的属性'ngIf'”

提前致谢。

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 { }

【问题讨论】:

  • 似乎对我有用,你能尝试在 stackblitz 中重现吗?
  • 请访问stackblitz.com/edit/clear-templateref,尝试点击文本“Hello cpIf Directive”并检查您的控制台。

标签: angular typescript angular2-directives


【解决方案1】:

您只是无法在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;
}

哦,是的,最重要的是,箭头函数可以在不改变任何内容的情况下工作,抱歉我之前没有考虑过这个:)

箭头函数不会创建自己的 this 上下文,所以 this 有 它的原始含义来自封闭的上下文。

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

Ref

【讨论】:

  • 谢谢 :-) :-。你是快速修复者。 :-)
  • 如果您能再解决一个问题,我将不胜感激,为什么“Hello cpIf 指令”会重复两次?
  • @AmitV 因为this.viewContainer.createEmbeddedView(this.templateRef); 这一行
  • 好的。再次感谢 :-) :-)
猜你喜欢
  • 2018-06-28
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 2019-11-14
  • 2021-09-08
  • 1970-01-01
  • 2018-09-21
  • 2013-07-26
相关资源
最近更新 更多