I'd like to implement the common Angular 1.x pattern of having child directives within a parent directive in Angular 2. Here's my desired structure.
<foo>
<bar>A</bar>
<bar>B</bar>
<bar>C</bar>
</foo>
I'd like for these Bar
components to have click
events that get emitted to the Foo
component.
Here's my Foo
so far:
@Component({
selector: 'foo',
template: `
<div>
<ng-content></ng-content>
</div>
`
})
export class Foo {
@ContentChildren(Bar) items: QueryList<Bar>;
}
And here's my Bar
:
@Component({
selector: 'Bar',
template: `
<div (click)="clickity()">
<ng-content></ng-content>
</div>
`
})
export class Bar {
clickity() {
console.log('Broadcast this to the parent please!');
}
}
How do I go about notifying Foo
whenever one of its Bars
is clicked?
@Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component. Conversely, @Output() lets the child send data to a parent component.
To call function on child component on parent events with Vue. js, we can assign the ref to the child component and then call the method in the parent when the event is emitted. to add a template with the child-component added. We assign a ref to it.
So to emit an event from the child component class to the parent component class, use EventEmitter with the @Output() decorator.
You can use a service to send data between components if you can't do it using @Output()
decorator. Here's an example:
import {EventEmitter} from 'angular2/core';
export class EmitterService {
private static _emitters: { [channel: string]: EventEmitter<any> } = {};
static get(channel: string): EventEmitter<any> {
if (!this._emitters[channel])
this._emitters[channel] = new EventEmitter();
return this._emitters[channel];
}
}
You import it wherever you need to emit or subscribe to an event:
// foo.component.ts
import {EmitterService} from '../path/to/emitter.service'
class Foo {
EmitterService.get("some_id").subscribe(data => console.log("some_id channel: ", data));
EmitterService.get("other_id").subscribe(data => console.log("other_id channel: ", data));
}
// bar.component.ts
import {EmitterService} from '../path/to/emitter.service'
class Bar {
onClick() {
EmitterService.get("some_id").emit('you clicked!');
}
onScroll() {
EmitterService.get("other_id").emit('you scrolled!');
}
}
another example: plunker
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With