首页 文章

Angular 2:直接父组件不监听子组件发出的事件

提问于
浏览
0

我有一个基本的角应用程序,有3个组件如下:

  • car-component 这是主要或父组件 .

  • carousel-component (汽车零件的子,*使用ng-content)

  • child-component (旋转木马组件之子)

子组件内的按钮在单击时使用EventEmitter()发出事件 . 正如您从plunker中的代码中看到的那样,汽车组件(主要组件或主组件)能够监听并捕获其 child's child component (即 child-component.ts )发出的事件,并且{}在汽车中更新 - 组件模板 .

但是,作为子组件的直接父级的 carousel-component 无法捕获相同的事件,并且在carousel-component内部没有更新文本 .

car-component.ts

import  {Component} from 'angular2/core';
import {CarouselComponent} from './carousel-component';
import {Child} from './child.component';

@Component({
    selector: 'my-app',
    template: `
              <div style="border:1px solid #CCC; padding: 5px; margin: 5px;">
                car-comp txt: {{text}}
                <carousel-component>
                    <child (changed)="onChange($event)"></child>
                </carousel-component>
              </div>
    `,
    directives : [Child, CarouselComponent]
})
export class CarComponent {

    text: string = '?';

    onChange(value) {
        console.log('car-component onChange fn..');
       this.text = value;
    }

}

carousel-component.ts

import  {Component, EventEmitter} from 'angular2/core';
import {Output} from 'angular2/core';

@Component({
    selector: 'carousel-component',
    template: `
                <div style="background: #CCC; padding: 10px;">
                <div>carousel-component txt: {{carouselTxt}}</div>
                <ng-content></ng-content>
                </div>
             `,
})
export class CarouselComponent {

    carouselTxt: string = '?';

    changed = new EventEmitter();

    onChange(value) {
        console.log('carousel-comp onChange called..');
        this.carouselTxt = value;
    }

}

child.component.ts

import  {Component, EventEmitter} from 'angular2/core';
import {Output} from 'angular2/core';

@Component({
    selector: 'child',
    template: `
                <div style="background: #FFF; padding: 10px;">
                child-comp txt: 
                <input type ="text" #textInput value="{{txt}}">
                <button (click)="onChange(textInput.value)">Emit</button>
                </div>
             `,
    outputs:['changed']
})
export class Child {

    txt: string = 'abc';

    changed = new EventEmitter();

    onChange(value) {
        this.txt = value;
        this.changed.emit(value);
    }

}

有人可以让我知道我在哪里错了吗?

https://plnkr.co/edit/h9mjlo?p=preview

3 回答

  • 0

    在CarouselComponent中使用ContentChildren和ngAfterContentInit,无需添加服务'或'将模板移出汽车组件模板 .

    export class CarouselComponent {
    
        carouselTxt: string = '?';
    
        @ContentChildren(Child) childItems:QueryList<Child> = new QueryList<Child>();
    
        ngAfterContentInit () {
          this.childItems.toArray().forEach((item, n)=>{
            item.changed.subscribe(
              (val)=> { this.carouselTxt = val; },
              (e)=> { console.log('e::', e); },
              (c)=>{ console.log('c::', c); }
            );
          });
        }
    
    }
    

    解决方案:https://plnkr.co/edit/x2mO0r?p=preview

  • 0

    在您的汽车组件中,您正在监听孩子的事件已更改并将其绑定到onChange . 由于这是在你的汽车零部件模板中,它只将它绑定到汽车零部件的onChange方法,而不是carousel-component .

    要创建子组件's change event visible to all of it'的分层父级,请创建所有父级订阅的服务 . 有关如何执行此操作的指南,请访问:https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

  • 0

    正如@Ricardo的最后一个回答中所提到的,car-component正在为子组件提供selctor . 要在carousel-component中侦听事件,请从car-component模板中删除子组件,并将其添加到carousel-component模板中 . 并且您可以在旋转木马组件中再添加一个事件 Launcher ,它将到达汽车组件的父级 . 你可以通过onChange()获取该事件

相关问题