如何从父级向子级发送事件?

我目前使用角度2。通常我们使用 @Output() addTab = new EventEmitter<any>();,然后 addTab.emit()发出一个事件的父组件。

有没有什么办法可以让我们从父母到孩子都这样做呢?

178181 次浏览

使用子组件中的@Input ()装饰符允许父组件绑定到此输入。

在子组件中声明如下:

@Input() myInputName: myType

要将属性从父级绑定到子级,必须在模板中添加绑定括号和它们之间输入的名称。

例如:

<my-child-component [myChildInputName]="myParentVar"></my-child-component>

但是要注意,对象是作为引用传递的,所以如果对象在子对象中更新,那么父对象的 var 就会过于更新。 这可能会导致某些不必要的行为。 对于主类型,将复制该值。

进一步阅读:

医生: https://angular.io/docs/ts/latest/cookbook/component-communication.html

据我所知,有两种标准的方法可以做到这一点。

1.@Input

每当父级中的数据发生更改时,子级都会在 NgOnChanges 方法。子元素可以对其进行操作。这是标准 与孩子互动的方式。

// Parent-Component
public inputToChild: Object;
        

// Parent-HTML
<child [data]="inputToChild"> </child>
        

//Child-Component
@Input() data;


ngOnChanges(changes: { [property: string]: SimpleChange }) {
// Extract changes to the input property by its name
let change: SimpleChange = changes['data'];


// Whenever the data in the parent changes, this method gets triggered
// You can act on the changes here. You will have both the previous
// value and the  current value here.
}
  1. 共享服务理念

创建服务并在共享服务中使用可观察到的内容 订阅,每当有变化,孩子将被通知。这也是一种流行的方法。当您希望发送除作为输入传递的数据之外的其他内容时,可以使用。

// SharedService
subject: Subject<Object> = new Subject<Object>();


// Parent-Component
constructor(sharedService: SharedService)
this.sharedService.subject.next(data);


// Child-Component
constructor(sharedService: SharedService) {
this.sharedService.subject.subscribe((data) => {
// Whenever the parent emits using the next method,
// you can receive the data in here and act on it.
});

在父级中,可以使用@ViewChild 引用子级。当需要时(例如,当事件被激发时) ,您可以使用@ViewChild 引用在子级中执行一个方法。

使用 RxJ,您可以在父组件中声明一个 Subject,并将其作为 Observable传递给子组件,子组件只需要订阅这个 Observable

父组件

eventsSubject: Subject<void> = new Subject<void>();


emitEventToChild() {
this.eventsSubject.next();
}

家长-HTML

<child [events]="eventsSubject.asObservable()"> </child>

子组件

private eventsSubscription: Subscription;


@Input() events: Observable<void>;


ngOnInit(){
this.eventsSubscription = this.events.subscribe(() => doSomething());
}


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

在父组件中,可以使用@ViewChild ()访问子组件的方法/变量。

@Component({
selector: 'app-number-parent',
templateUrl: './number-parent.component.html'
})
export class NumberParentComponent {
@ViewChild(NumberComponent)
private numberComponent: NumberComponent;
increase() {
this.numberComponent.increaseByOne();
}
decrease() {
this.numberComponent.decreaseByOne();
}
}

更新:

角度8向前-

@ViewChild(NumberComponent, { static: false })

以前的解决方案都不适合我,因为我有一个嵌套的递归子组件。因此,我通过使用 OnChanges 函数使用了以下方法。

父组件

buttonToggle: boolean = false;


buttonClick(): void {
this.buttonToggle = !this.buttonToggle;
}

父 HTML

<appNestedChildItemComponent [buttonTrigger]="buttonToggle"></appNestedChildItemComponent>

递归嵌套子组件

export class NestedChildItemComponent implements OnInit, OnChanges {


@Input() buttonTrigger: boolean;
buttonToggle: boolean = false;


ngOnInit() {
this.buttonToggle= buttonToggle;
}


ngOnChanges(changes: SimpleChanges) {
if (changes['buttonTrigger'] && changes['buttonTrigger']?.previousValue != changes['buttonTrigger']?.currentValue) {
this.buttonToggle= !this.buttonToggle;
// Do Something triggered by the parent button.
}
}
}

关于共享服务的相同概念: 还可以使用带有属性管理的本地存储。 父级将更新存储中的状态,子级(ren)可以订阅存储本身。

这种方法使得多对多事件/数据/信息传输更加容易,并且可以应用原始问题。

缺点: 更重 优势: 对大型应用程序演化更加健壮

我推荐一个商店管理库的例子: https://github.com/ngneat/elf