首页 > 解决方案 > ViewChild 返回“未定义”-Angular2

问题描述

我正在尝试通过在父组件上按下按钮来执行子组件的功能,但由于某种原因它未定义。

家长:

.. com1.html
  <ng-template #content let-c="close" let-d="dismiss">
    <div class="modal-header">
      <h4 class="modal-title">Title</h4>
    </div>
    <div class="modal-body" style="display: flex; justify-content: center;">
      <app-com2 [var1]="value" #traceRef></app-com2>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-outline-dark" (click)="savePNG()"><i class="fa fa-download"></i>PNG</button>
      <button type="button" class="btn btn-outline-dark" (click)="c()">Close</button>
    </div>
  </ng-template>

<button class="btn btn-sm btn-secondary" (click)="open(content)">Button</button>

...com1.ts
export class com1 implements OnInit {
@ViewChild('traceRef') traceRef;
value = "something";

  constructor(private modalService: NgbModal) {}

  savePNG() {
    this.traceRef.savePNG();
  }

  open(content: any) {
    this.modalService.open(content, { windowClass: 'temp-modal' });
  }
}

谁能指出我正确的方向,因为其他线程没有帮助:(即使使用 ngAfterViewInit 它仍然未定义。

标签: angularviewchild

解决方案


它无法正常工作的原因ng-templateNgbModal服务创建模板并且不将其附加到父视图而是附加到根ApplicationRef

const viewRef = content.createEmbeddedView(context);
this._applicationRef.attachView(viewRef);

https://github.com/ng-bootstrap/ng-bootstrap/blob/0f8055f54dad84e235810ff7bfc846911c168b7a/src/modal/modal-stack.ts#L107-L109

这意味着您的查询对于您的组件将始终不脏。

在常见情况下(参见@ConnorsFan提供的示例),我们使用vcRef.createEmbeddedView它负责检查父视图中的查询:

vcRef.createEmbeddedView
          ||
          \/
function attachEmbeddedView(
   ...
  Services.dirtyParentQueries(view);  <========== set dirty for queries

https://github.com/angular/angular/blob/0ebdb3d12f8cab7f9a24a414885ae3c646201e90/packages/core/src/view/view_attach.ts#L12-L23

我在这里看到的简单解决方案是直接在模板中传递或调用引用:

(click)="traceRef.savePNG()"

推荐阅读