本文是阅读有关 Angular 的元件生命周期的 OnChanges
的笔记内容。
呼叫时机: 当元件中的 @Input
类型的属性,发生变化的时候,这个 lifecycle hook 就会被呼叫。
例如:
[TypeScript]
import { OnChanges, SimpleChanges, Input} from '@angular/core';
export class AppComponent implements OnChanges {
@Input() book;
ngOnChanges(changes: SimpleChanges) {
console.log(this.book);
}
}
上面的范例中,可以看到在这个元件里面定义了一个 @Input 的属性 book,每当 book 的内容有变化的时候,就会触发到 ngOnChanges
的 hook 喔。
而 ngOnChanges
会自带一个参数,他是一个物件,里面会包含的内容为 @Input 属性的现在的值和上一次的值。
这边我们先来写个 @Input
和 ngOnChanges
的范例
[子元件 - TypeScript]
@Component({
selector: 'bcomp',
template: `
<div *ngFor="let user of users">
{{ user }}
</div>
`
})
export class BComponent implements OnChanges {
@Input() users
ngOnChanges() {
console.log("changed")
}
}
[父元件 - TypeScript]
@Component({
template: `
<bcomp [users]="users"></bcomp>
`
})
export class App {
users = ["Jasper", "Tom", "Mary"]
}
可以看到在子元件定义了一个 @Input property 叫做 users,并把这个属性绑到父元件的里面,去接收来自父元件的 users 内容。
上面的内容,会呈现如下的画面
就很单纯的把资料渲染到画面上。
那如果今天当点击某个按钮,会逐一删除 users 里面的内容,那承如上面所讲过的当 @Input 属性的内容改变的时候,照道理讲子元件的 ngOnChanges 这个 hook 会被触发。
那来改写一下上面的范例吧
[子元件 - TypeScript]
export class BComponent implements OnInit, OnChanges {
@Input() users;
ngOnChanges(obj: SimpleChanges) {
console.log(obj);
}
}
[父元件 - TypeScript]
@Component({
template: `
<app-b [users]="users"></app-b>
<button (click)="delete()">delete</button>
`,
})
export class AppComponent {
users = ['Jasper', 'Tom', 'Mary'];
delete() {
this.users.splice(0, 1);
}
}
可以看到上面的范例,在父元件有个 delete 的函式,每当点击按钮就会触发它,并删除 users 的阵列的内容。
操作画面如下
可以看到画面上的阵列内容,确实地逐一被删除,但是, console.log 中并没有触发子元件的 ngOnChanges 里面的内容,将改变的内容印出来。
原因是什麽呢?
因为,users 阵列透过 splice 来删除它的阵列内容,但并没有改变它阵列的位址,所以,对 @Input
属性 users 来说,它都是指向同一个位址的阵列,尽管它内容有被删减,对 @Input 属性 users 来讲还是同一个人根本没变化,所以,才没有触发它的 ngOnChanges 内容罗。
那要怎麽改呢?
很简单,我们就用那种会回传新阵列的删除方法,也就是 slice
。
那我们来改写一下,父元件的内容
[父元件 - TypeScript]
@Component({
template: `
<app-b [users]="users"></app-b>
<button (click)="delete()">delete</button>
`,
})
export class AppComponent {
users = ['Jasper', 'Tom', 'Mary'];
delete() {
this.users = this.users.slice(1);
}
}
你可以看到,我们把经过 slice 删除後产生的阵列回传给原本的 users,让它去指向另一个位址的新阵列。
操作结果如下
可以看到子元件的 ngOnChanges 函式就会被触发罗,而且我们可以透过印出 ngOnChanges 参数内容,去看每一次子元件的 users 阵列内容是真的也被删除掉了。
来做个总结
ngOnChanges
会在元件的 @Input
属性有改变的时候,被触发。@Input
内容的传址问题,会导致子元件的 ngOnChanges
不会被触发,若要改变这种现象的话,就必须使用 non-mutating method (也就是会回传新的物件的方式) 来达成。
<<: day8: CSS style 规划 - CSS in JS(emotion 使用 - 2)
资料型别 为何需判断型别,其因为电脑在执行时,需先判断资料是何种型别,才可采取运算方式。例如数字12...
如果画面太小或看不清楚,可移驾至 https://www.youtube.com/watch?v=...
前一天,我们简单讨论了一下面对缺失值资料的处理 那今天就反过来讨论一下面对资料中有重复的情况应该要怎...
前面学习了基础的变数与运算子的使用,这些基础往往是非常枯燥乏味的,还没有与电脑有更进一步的互动,所...
在上一篇开始进到终端机的操作後,我们接着要来把一些东西真正让git来进行版本控制。 在这个章节,主要...