我问这个问题是为了更好地理解变量检测在Angular中的工作原理。
我知道当服务中声明的变量发生变化时,我应该使用RxJS
来通知组件。
我感兴趣的是为什么Angular会检测到数组和对象的更改,而不是字符串变量。
这是一个例子
服务在3秒后更改字符串,数组和对象
import { Injectable } from '@angular/core';
@Injectable()
export class NameService {
name = '';
list = [];
obj = {
a: 'something'
};
constructor() {
setTimeout(() => {
this.name = 'Name changed';
this.list.push('a', 'b');
this.obj.a = 'obj.a changed';
}, 3000);
}
}
成分</ P>
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { NameService } from './name.service';
@Component({
selector: 'my-app',
template: `
<div>{{name}}</div>
<div>{{list | json }}</div>
<div>{{obj | json }}</div>`,
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
name = '';
list = [];
obj = {};
constructor(private nameService: NameService) { }
ngOnInit() {
this.name = this.nameService.name;
this.list = this.nameService.list;
this.obj = this.nameService.obj;
}
}
Angular检测到 list
和obj
更改,但name
未检测到。这是否会发生,因为数组和对象是可变的,字符串是不可变的?
答案 0 :(得分:3)
简单的原因是this.list = this.nameService.list;
和this.obj = this.nameService.obj;
正在为左侧指定一个数组或对象的引用(指针)。
当内容被添加到数组或对对象的值进行更改时,正在更改的是数组/对象的内容而不是指向列表或对象的指针,在这种情况下,这是什么已分配到this.list
和this.obj
。
另一方面,this.name = this.nameService.name;
正在为this.name分配确切的值。
那么数据的变化如何传播?
创建组件时,ngOnInit()
lifecycle hook仅被调用一次。它是在服务上的值被复制到组件中的变量的时间点,在您的情况下如下所示。
this.name = this.nameService.name; // The actual value is assigned to this.name
this.list = this.nameService.list; // The pointer to the list in memory is assigned to this.list
this.obj = this.nameService.obj; // The pointer to the object in memory is assigned to this.obj
3秒后执行setTimeout
回叫功能时,
name
变量的值已更改this.nameService.list/obj
时检索的实际值保持不变 )一旦更改了检测周期,Angular将呈现其拥有的内容。
如果是name
变量,它会呈现静态值。在list/obj
的情况下,它读取列表/对象的内容,各个指针(自初始化后引用从未改变)指向并呈现新内容(即已更新的内容)。
<强>更新: - 强>
此article提供了有关变更检测如何运作的深入应用。