I updated from RC1 to RC2 and got this cryptic message - "Expression has changed after it was checked". The code is very simple.
The parent component has two children "sister" and "brother". Right after init, sister emits an event that is assigned to parent's variable and brother's Input() property is bound to the same variable. I think this is "classic" communication between siblings components using parent's variable.
It used to work in RC1, but not is RC2. I checked CHANGELOG.md, but have found no clue. What am I doing wrong?
http://plnkr.co/edit/HMPAbImpWWeZrVjHyb6H?p=preview
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'brother',
template:'<h2>Brother has {{present}}</h2>'
})
export class Brother{
@Input() present: string;
}
@Component({
selector: 'sister',
template:'<h2>Sister has {{_present}}</h2>'
})
export class Sister{
@Output() present: EventEmitter<string> = new EventEmitter;
public _present: string = 'something';
ngOnInit(){
this.present.emit(this._present);
}
}
@Component({
selector: 'my-app',
template: `
<div class="container">
<h2>Parent has {{present}}</h2>
<brother [present]="present"></brother>
<sister (present)="present=$event"></sister>
</div>
`,
directives:[Brother,Sister]
})
export class AppComponent {
public present: string;
}
Yes, it has changed a bit. Specifically
fix(facade): change EventEmitter to be sync by default (#8761)
https://github.com/angular/angular/commit/e5904f4
So if you change your code from:
@Output() present: EventEmitter<string> = new EventEmitter;
to:
@Output() present: EventEmitter<string> = new EventEmitter(true);
Then it should work and you'll get the same behavior.
See also https://github.com/angular/angular/blob/master/modules/%40angular/facade/src/async.ts#L152
http://www.bennadel.com/blog/3071-synchronous-vs-asynchronous-eventemitters-in-angular-2-beta-14.htm
Angular is processing template top-to-bottom, brother is checked first, sister is checked second. Sister fires synchronous event and changes brother field right after it(brother) has been checked. Angular detects this kind of errors in debug mode, in production mode this change will leave undetected(template will not be updated) until next detector pass. You can change order of components in app template and error will go away:
<sister (present)="present=$event"></sister>
<brother [present]="present"></brother>
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