簡體   English   中英

ng-template中的Angular 6嵌套ViewChild為null

[英]Angular 6 nested ViewChild inside ng-template is null

我們在應用程序中使用模式( ng-bootstrap的模式)。 該模態如下所示:

<ng-template #modal let-modal>
    <app-audio #audio></app-audio>
</ng-template>

這是邏輯:

@ViewChild('modal')
modal: ElementRef;

@ViewChild('audio')
audio: AudioComponent;

使用以下方式打開模態:

this.modalService.open(this.modal,{size:'lg'});

一切都很好,直到這里。 模態打開,並顯示音頻組件。 但是現在,我們想要訪問組件內部的邏輯,以及執行類似的操作時:

this.audio.somePublicComponentFunction()

碰巧this.audio為null。 我已經嘗試過讓孩子使用角度的變化檢測器,但是無法找到一種將this.audio與實際組件正確鏈接的方法。 有任何想法嗎? 非常感謝。

您可以在這里看到問題:stackblitz.com/edit/angular-ofmpju

您可以像這樣不使用refrence變量讀取子組件

@ViewChild(AudioComponent)
audio: AudioComponent;

這將為您提供子組件的實例-您可以在其中訪問方法

this.audio.someComponentFunction()

您的html

<ng-template #modal let-modal>
    <app-audio></app-audio>
</ng-template>

我認為這將解決您的問題-編碼愉快

更新:

希望我找到了解決此問題的方法-如果您只想觸發一個功能,則可以使用此方法

我剛剛使用gettersetter添加了一個屬性,並在set值時觸發了該函數

@Input()
  get triggerFunction(): boolean {
    return this.runFuntion;
  }

  set triggerFunction(value: boolean) {
    this.runFuntion = value;
    this.someFunction();
  }  

因此,這會導致每次顯示模型時都觸發該函數-上述屬性屬於嵌套在<ng-template>內部的子組件,因此最終,模型模板將如下所示:

<ng-template #modal let-modal>
  <app-audio [triggerFunction]="true"></app-audio>
</ng-template>

希望這現在可以解決問題-謝謝

您可以從模板本身調用方法audio.someFunction()

<ng-template #modal let-modal>
  <div style="background-color: red;"> 
  <h1>Modal header</h1>
  <app-audio #audio></app-audio>
  <!-- on click, call audio comp method someFunction() using its reference --> 
  <button (click)="audio.someFunction()">Operate with audio from inside modal</button>
  </div>
</ng-template>

這里不需要@ViewChild屬性。 這應該為您解決問題。

分叉演示

對我來說,所有這些解決方案都行不通,我仍然想在第三方ng-template中訪問自己的組件。 這是我的“解決方案”。 我不認為這是最佳實踐,而是一個拼命的解決方案,可以得到我想要的;-)當然,它僅適用於您自己的組件。

// mycomponent.ts => component that needs to be accessed 
import { Component, Output, EventEmitter, AfterViewInit } from '@angular/core';

@Component({
    selector: 'my-component',
    templateUrl: './mycomponent.html'
})
export class MyComponent implements AfterViewInit {
   @Output() initialized: EventEmitter<MyComponent> = new EventEmitter<MyComponent>();

   ngAfterViewInit(): void {
        this.initialized.emit(this);
   }

   reload(): void {
        // Do something
   }
}


// somecomponent.html => component with <ng-template> holding MyComponent

<ng-template>
    <div class="btn-group ml-2">
      <my-component (initialized)="onMyComponentInitialized($event)"></my-component>
    </div>
</ng-template>


// somecomponent.ts => component with <ng-template> holding MyComponent
import { Component, OnDestroy } from '@angular/core';
import { MyComponent } from '../../my-component';

@Component({
    selector: 'some-component',
    templateUrl: './some-component.html'
})
export class SomeComponent implements OnDestroy {
    private _myComponent: MyComponent = null;

    onMyComponentInitialized(component: MyComponent) {
        this._myComponent = component;
    }

    someOtherMethod() {
        if (this._myComponent) {
            // Call some method on the component
            this._myComponent.reload();
        }
    }

    ngOnDestroy() {
        this._myComponent = null;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM