No momento, estou usando o Angular 2. Normalmente usamos @Output() addTab = new EventEmitter<any>();
e addTab.emit()
para emitir um evento para o componente pai.
Existe alguma maneira de fazermos vice-cersa, de pai para filho?
No momento, estou usando o Angular 2. Normalmente usamos @Output() addTab = new EventEmitter<any>();
e addTab.emit()
para emitir um evento para o componente pai.
Existe alguma maneira de fazermos vice-cersa, de pai para filho?
Respostas:
Usando RxJs , você pode declarar um Subject
em seu componente pai e passá-lo como Observable
componente filho, o componente filho só precisa se inscrever nele Observable
.
Componente-pai
eventsSubject: Subject<void> = new Subject<void>();
emitEventToChild() {
this.eventsSubject.next();
}
HTML pai
<child [events]="eventsSubject.asObservable()"> </child>
Componente-filho
private eventsSubscription: Subscription;
@Input() events: Observable<void>;
ngOnInit(){
this.eventsSubscription = this.events.subscribe(() => doSomething());
}
ngOnDestroy() {
this.eventsSubscription.unsubscribe();
}
this.eventsSubject.next({data});
no pai, depois this.events.subscribe(({data}) => doSomething(data));
no filho.
eventsSubject
para um Observable em vez de apenas inscrevê-lo como um Assunto?
Pelo que eu sei, existem 2 maneiras padrão de fazer isso.
1. @Input
Sempre que os dados no pai são alterados, o filho é notificado sobre isso no método ngOnChanges. A criança pode agir sobre isso. Esta é a maneira padrão de interagir com uma criança.
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.
}
Criando um serviço e usando um observável no serviço compartilhado. A criança assina e sempre que houver alteração, ela será avisada. Este também é um método popular. Quando você quiser enviar algo diferente dos dados que você passou como entrada, isso pode ser usado.
SharedService
subject: 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.})
<child [data]="inputToChild"> </child>
provavelmente deve ser <child [data]="(inputToChild)"> </child>
para obter as alterações
Em um componente pai, você pode usar @ViewChild () para acessar o método / variável do componente filho.
@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();
}
}
Atualizar:
Angular 8 em diante -
@ViewChild(NumberComponent, { static: false })
numberComponent
estará undefined
.
Use o decorador @Input () em seu componente filho para permitir que o pai se vincule a esta entrada.
No componente filho, você o declara como está:
@Input() myInputName: myType
Para vincular uma propriedade de pai a filho, você deve adicionar em seu modelo os colchetes de ligação e o nome de sua entrada entre eles.
Exemplo:
<my-child-component [myChildInputName]="myParentVar"></my-child-component>
Mas cuidado, os objetos são passados como referência, portanto, se o objeto for atualizado no filho, o var do pai também será atualizado. Isso pode levar a algum comportamento indesejado em algum momento. Com tipos primários, o valor é copiado.
Para ir mais longe, leia isto:
Documentos: https://angular.io/docs/ts/latest/cookbook/component-communication.html
No pai, você pode fazer referência ao filho usando @ViewChild. Quando necessário (ou seja, quando o evento seria disparado), você pode apenas executar um método no filho do pai usando a referência @ViewChild.