@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
`})
class UserDetail {
user: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
}
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
`})
class UserDetail {
user: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
addMoney() {
this.user.money += 10;
}
}
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
<button (click)="addMoney()">Add money</button>
`})
class UserDetail {
user: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
addMoney() {
this.user.money += 10;
}
}
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
<button (click)="addMoney()">Add money</button>
`})
class UserDetail {
user: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
addMoney() {
this.user.money += 10;
}
}
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
<button (click)="addMoney()">Add money</button>
`})
class UserDetail {
user: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
addMoney() {
this.user.money += 10;
}
}
@FilipMam
@FilipMam
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
`})
class UserDetail {
@Input()
user: User;
}
@FilipMam
@Component({
template: `
<user [user]="userFromParent"></user>
<button (click)="addMoney()">Add money</button>
`})
class ParentComponent {
userFromParent: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
addMoney() {
this.userFromParent.money += 10;
}
}
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
class AppMain {
constructor(private zone: NgZone) {
this.zone.asyncEventDone
.subscribe(() => runAngularChangeDetection());
}
}
@FilipMam
C
C
C
C
C
C
C
C
C
C
@FilipMam
V
V
V
V
V
V
V
V
V
V
@FilipMam
view: View = {
component: Component = {...},
...
}
@FilipMam
class AppMain {
constructor(private zone: NgZone) {
this.zone.asyncEventDone
.subscribe(() => runAngularChangeDetection(this.rootView));
}
}
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
view: View = {
component: Component = {...},
oldValues: any[] = ["Luke", "Skywalker", "100"],
newValues: any[] = ["Luke", "Skywalker", "110"],
}
...
user: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
user: User = {
name: "Luke",
lastName: "Skywalker",
money: 110
}
@FilipMam
class AppMain {
constructor(private zone: NgZone) {
this.zone.asyncEventDone
.subscribe(() => runAngularChangeDetection(this.rootView));
}
}
@FilipMam
runAngularChangeDetection(view: View) {
view.oldValues.forEarch((value, i) => {
if (value !== view.newValues[i]) {
rerenderNewValue(i)
}
});
}
@FilipMam
runAngularChangeDetection(view: View) {
view.oldValues.forEarch((value, i) => {
if (value !== view.newValues[i]) {
rerenderNewValue(i)
}
});
view.children.forEach(runAngularChangeDetection)
}
@FilipMam
["Luke", "Skywalker", "100"]
["Luke", "Skywalker", "110"]
@FilipMam
@FilipMam
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
`})
class UserDetail implements AfterViewInit {
user: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
ngAfterViewInit() {
this.user.name = "Anakin";
}
}
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
`})
class UserDetail implements AfterViewInit {
user: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
ngAfterViewInit() {
this.user.name = "Anakin";
// trigger change detection here
}
}
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
`})
class UserDetail implements AfterViewInit {
constructor(cd: ChangeDetectorRef) {}
user: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
ngAfterViewInit() {
this.user.name = "Anakin";
this.cd.detectChanges();
}
}
@FilipMam
this.cd.detectChanges()
@FilipMam
this.cd.detectChanges()
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
runAngularChangeDetection(view: View) {
view.oldValues.forEarch((value, i) => {
if (value !== view.newValues[i]) {rerenderNewValue[i]}
});
view.children.forEach(runAngularChangeDetection)
}
@FilipMam
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
class UserDetail {
@Input();
user;
}
@FilipMam
runAngularChangeDetection(view: View) {
view.oldValues.forEarch((value, i) => {
if (value !== view.newValues[i]) {rerenderNewValue[i]}
});
view.children.forEach(runAngularChangeDetection)
}
@FilipMam
runAngularChangeDetection(view: View) {
if (view.checksEnabled) {
view.oldValues.forEarch((value, i) => {
if (value !== view.newValues[i]) {rerenderNewValue[i]}
});
view.children.forEach(runAngularChangeDetection)
}
}
@FilipMam
@Component({
changeDetection: ChangeDetectionStrategy.OnPush
})
view: View = {
checksEnabled: false
}
...
@Component({
changeDetection: ChangeDetectionStrategy.Default
})
view: View = {
checksEnabled: true
}
@FilipMam
runAngularChangeDetection(view: View) {
if (view.checksEnabled) {
checkProperties(view);
view.children.forEach(runAngularChangeDetection)
}
}
...
checkProperties(view: View) {
view.oldValues.forEarch((value, i) => {
if (value !== view.newValues[i]) {rerenderNewValue[i]}
});
}
@FilipMam
F
F
F
F
F
F
F
F
F
F
@FilipMam
F
F
F
F
F
F
F
F
F
F
@FilipMam
T
F
F
F
F
F
F
F
F
F
@FilipMam
runAngularChangeDetection(view: View) {
if (view.checksEnabled) {
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
}
@FilipMam
T
F
F
F
F
F
F
F
F
F
if (view.checksEnabled) { // false
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
@FilipMam
T
T
T
F
F
F
F
F
F
F
@FilipMam
T
T
T
F
F
F
F
F
F
F
if (view.checksEnabled) { // true
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
@FilipMam
T
T
T
F
F
F
F
F
F
F
if (view.checksEnabled) { // false
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
@FilipMam
T
T
T
F
F
F
F
F
F
F
@FilipMam
T
T
T
F
F
F
F
F
F
F
if (view.checksEnabled) { // true
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
@FilipMam
T
T
T
F
F
F
F
F
F
F
if (view.checksEnabled) { // true
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
@FilipMam
T
T
T
F
F
F
F
F
F
F
if (view.checksEnabled) { // false
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
@FilipMam
@FilipMam
T
T
T
F
F
F
F
F
F
F
if (view.checksEnabled) { // ??
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
@FilipMam
runAngularChangeDetection(view: View) {
if (view.checksEnabled) {
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
}
@FilipMam
runAngularChangeDetection(view: View) {
if (inputsValuesHaveChanged(view)) {
view.checksEnabled = true;
}
if (view.checksEnabled) {
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
}
@FilipMam
View {
oldInputsValues: any[];
inputsValues: any[];
}
@FilipMam
inputsValuesHaveChanged(view: View): boolean {
view.oldInputValues.any((oldValue, index) => {
return oldValue !== view.values[index];
})
}
@FilipMam
@Component({
template: `
<user [user]="userFromParent"></user>
<button (click)="addMoney()">Add money</button>
`})
class ParentComponent {
userFromParent: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
addMoney() {
this.userFromParent.money += 10;
}
}
@FilipMam
T
T
T
F
F
F
F
F
F
F
if (view.checksEnabled) { // ??
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
@FilipMam
T
T
T
F
F
F
F
F
F
F
if (view.checksEnabled) { // false
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
@FilipMam
inputsValuesHasChanged(view: View): boolean {
view.oldInputValues.any((oldValue, index) => {
return oldValue !== view.values[index];
})
}
@FilipMam
@Component({
template: `
<user [user]="userFromParent"></user>
<button (click)="addMoney()">Add money</button>
`})
class ParentComponent {
userFromParent: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
addMoney() {
this.userFromParent.money += 10;
this.user = {...this.userFromParent, money: this.userFromParent.money + 10};
}
}
@FilipMam
T
T
T
F
F
F
T
F
F
F
if (view.checksEnabled) { // true
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
@FilipMam
@Component({
template: `
<user [user]="userFromParent"></user>
<button (click)="addMoney()">Add money</button>
`})
class ParentComponent {
userFromParent: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
addMoney() {
this.userFromParent.money += 10;
someImmutableApi.setValue(this.user.money, this.user.money + 10);
}
}
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
S
@FilipMam
@Injectable()
class UserService {
public user$: BevaviourSubject<User> = new BevaviourSubject<User>({
name: "Luke",
lastName: "Skywalker",
money: 100
});
public changeUser(): void {
this.user$.next({
name: "Obi Wan",
lastName: "Kenobi",
age: 2115
});
}
}
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
class UserDetail {
@Input();
user;
constructor(userService: UserService) {
userService.user$.subscribe(user => this.user = user);
}
}
@FilipMam
@Component({
template: `
<another-component></another-component>
<button (click)="addUser()">Add money</button>
`})
class ParentComponent {
constructor(private userService: UserService) {}
userFromParent: User = {
name: "Luke",
lastName: "Skywalker",
money: 100
}
addUser() {
this.userService.addUser();
}
}
@FilipMam
@FilipMam
S
@FilipMam
S
if (view.checksEnabled) { // false
checkProperties(view);
view.children.forEach(runAngularChangeDetection);
}
@FilipMam
S
@FilipMam
S
F
F
F
F
F
F
F
F
F
F
F
F
@FilipMam
S
F
F
F
T
T
F
F
F
F
F
F
F
@FilipMam
S
F
F
F
T
T
F
F
F
F
F
F
F
@FilipMam
S
F
F
F
T
T
T
T
T
F
F
F
T
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
class UserDetail {
@Input();
user;
constructor(userService: UserService) {
userService.user$.subscribe(user => {
this.user = user;
}
}
}
@FilipMam
@Component({
selector: "user",
template: `
<span>{{user.name}}</span>
<strong>{{user.lastName}}</strong>
<span class="money">({{user.money}}$)</span>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
class UserDetail {
@Input();
user;
constructor(userService: UserService, cd: ChangeDetectorRef) {
userService.user$.subscribe(user => {
this.user = user;
cd.markForCheck();
}
}
}
@FilipMam
S
F
F
F
T
T
T
T
T
F
F
F
T
cd.markForCheck()
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam
@FilipMam