javascript - 通过 View 中的 @ViewChild 调用组件上的方法到 QueryList

标签 javascript angular

我想做一个可重用的组件,设置多个子组件并一次渲染一个组件,我在父组件上有一组使用 @ContenChildren 获得的 View ,如下所示:

@ContentChildren(ChildComponent) children: QueryList<ChildComponent>;

//getCurrentChild function
getCurrentChild(){
   //index is a position of child
   return this.children.toArray()[this.index];
}  

并渲染父模板:

<ng-container *ngTemplateOutlet="getCurrentChild().content"></ng-container>

内容通过@ViewChild在子组件中渲染:

@ViewChild('currentChild') child;

模板如下所示:

<ng-template #currentChild>
  <ng-content>
  </ng-content>
</ng-template>

当我想实现这个结构时,我会这样做:

<parent>
    <child>
       <specific-one></specific-one>
    </child>
    <child>
       <specific-two></specific-two>
    </child>
</parent>

现在我在父组件中有一个方法,该方法在单击按钮时触发,并且需要调用特定组件中的方法(具体一或具体二取决于 currentChild):

export class SpecificOneComponent implements OnInit{

      action(){
          //this action will be called when parent is clicked
      }

}

我尝试通过子引用调用方法,但操作没有退出。还传递上下文,两者都没有。看来我在父模板中设置内容的方式不正确。

如有任何帮助,我们将不胜感激。

最佳答案

每个子组件都有自己的内容,因此这意味着仅获取对 ng-template 的引用就足够了,其中会有 ng-content.

此外,由于您希望在父级上发生特定事件时调用特定组件的方法,因此我们将使用一项服务,以便能够通知具体组件。

特定.service.ts

  private _shouldCallAction$ = new Subject();
  shouldCallAction$ = this._shouldCallAction$.asObservable();

  constructor() { }

  triggerAction (uniqueCompId) {
    this._shouldCallAction$.next(uniqueCompId);
  }

特定-{one|two|...n}.component.ts

这适用于依赖于父组件中发生的某些事件的每个组件。

  private shouldCallActionSubscription: Subscription;

  uniqueId: number | string;

  constructor(private specificService: SpecificService) {
    this.uniqueId = randomId();
  }

  ngOnInit() {
    this.shouldCallActionSubscription = this.specificService.shouldCallAction$
      .pipe(
        filter(id => id === this.uniqueId)
      )
      .subscribe(() => {
        console.log('calling action for specific-one')
      });
  }

  ngOnDestroy () {
    this.shouldCallActionSubscription.unsubscribe();
  }

child.component.html

<ng-container *ngIf="instanceIdx === crtIdx">
  <h3>trigger action of current specific component</h3>
  <button (click)="triggerAction()">trigger</button>
</ng-container>

<ng-template #currentChild>
  <ng-content></ng-content>
</ng-template>

child.component.ts

在这里,您还需要获取对specificComponent的引用,以获得其唯一ID

// Before class
let instances = 0;

@ViewChild('currentChild', { static: true }) tpl: TemplateRef<any>;
@ContentChild('specific', { static: true }) specificComp;

  get uniqueSpecificCompId () {
    return this.specificComp.uniqueId;
  }

  constructor (private specificService: SpecificService) {
    this.instanceIdx = instances++;
  }

  triggerAction () {

    this.specificService.triggerAction(this.uniqueSpecificCompId);
  }

父组件.ts

  @ViewChildren(ChildOneComponent) children: QueryList<ChildOneComponent>;
  @ViewChild('container', { static: true, read: ViewContainerRef }) container: ViewContainerRef;

  crtIdx = 0;

  ngAfterViewInit () {
    this.setNewView();
  }

  setNewView () {
    this.container.clear();

    this.container.createEmbeddedView(this.children.toArray()[this.crtIdx].tpl);
  }

  updateIndex (idx) {
    this.crtIdx = idx;

    this.setNewView();
  }

parent.component.html

<app-child [crtIdx]="crtIdx">
 <!-- ... -->
 <app-specific-two #specific></app-specific-two>
</app-child> 
<app-child [crtIdx]="crtIdx">
 <!-- ... -->
 <app-specific-one #specific></app-specific-one>
</app-child> 

<ng-container #container></ng-container>

<h3>Select a child</h3>

<button
  *ngFor="let _ of [].constructor(n); let idx = index;"
  (click)="updateIndex(idx)"
> 
  Select {{ idx + 1 }}
</button>

Here is the demo .

祝你好运!

关于javascript - 通过 View 中的 @ViewChild 调用组件上的方法到 QueryList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57515877/

相关文章:

javascript - 如何在 $http.post() 之后从 Angular 导航到 php 页面

javascript - 如何将焦点设置到下一个输入上的输入键按下 react js与refs

javascript - 类型错误 : Cannot read property 'findAll' of undefined

javascript - 为什么 Protractor 在连续两行引用元素时无法定位元素?

Angular 2 提供的参数与调用目标(spec.ts)的任何签名都不匹配

Angular - Google map API - 未捕获的 ReferenceError : google is not defined - only sometimes?

java - GWT、NoSuchElement 异常

javascript - Angular 翻译服务,在嵌套的 json 中插入参数

Angular 4 : View is not updating after model change?

javascript - 你能告诉我我的代码有什么问题吗?