首页 > 语言 > JavaScript > 正文

Angular2学习教程之ng中变更检测问题详解

2024-05-06 15:16:35
字体:
来源:转载
供稿:网友

开发中遇到的问题

在开发中遇到一个这样的问题,代码不便透露,这里用简单的例子还原一下问题所在:

有三个组件,第一个是用来展示Todo列表的组件TodoComponent,Todo是个类,包含id和name属性。

@Component({ selector: 'todo-list', template: `  <p *ngFor='let item of todos'>{{ item.name }}</p> `,})export class TodoComponent{ @Input() todos: Todo[]; public getTodos():Todo[]{  return this.todos; }}

第二个组件同样是一个Todo列表展示组件TodoDataComponent ,不同的是该组件需要一个TodoComponent类型的输入,并从TodoComponent组件中获得需要展示的Todo数据。

@Component({ selector: 'app-todo-data', template: `<p *ngFor='let item of todos'>{{ item.name }}</p>  <button (click)='getData()'>get data</button>`, styleUrls: ['./todo-data.component.css'], inputs: ['todoComponent'],})export class TodoDataComponent implements OnInit { todoComponent: TodoComponent; todos: Todo[] constructor() { } ngOnInit() { } getData(){  this.todos=this.todoComponent.getTodos(); }}

最后一个是应用的根组件,根组件根据loading值来确定是否加载TodoComponent组件,并展示TodoDataComponent 组件。

//app.component.htm<div> <div *ngIf='loading'>  <todo-list [todos]='todos'></todo-list>  <button (click)='changeall()'>next</button> </div></div><div> <app-todo-data [todoComponent]='todoComponent'></app-todo-data></div>//app.component.ts@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'],})export class AppComponent implements OnInit { todos: Todo[]; @ViewChild(TodoComponent) todoComponent: TodoComponent; loading: boolean = true; constructor(private todoService:TodoService){  super(true); } ngOnInit(){  this.todoService.todos.subscribe(data => {this.todos=data});  this.todoService.load(0, 3); } changeall(){  this.todoService.load(3, 3); }}

这样问题就来了,TodoComponent 组件是否在页面上展示是不确定的,在上面的例子中根组件最开始没有渲染TodoComponent组件,最后根据loading的值将TodoComponent渲染出来。而TodoDataComponent 组件的显示又需要一个TodoComponent 进行初始化(跟组件通过@ViewChild(TodoComponent)获得),这样造成在开发模式下出现以下错误:
template:9:16 caused by: Expression has changed after it was checked. Previous value: 'undefined'. Current value: '[object Object]'.

该错误仅在开发模式下会报告出来的,解决掉总是更好的选择,防止在生产环境下出现问题。

问题的原因及解决办法

这个问题是ng2中的变更检测策略造成的,ng2并没有智能到一有数据变更就能自动检测到的,执行变更检测的一些情况有:组件中的输入发生变化、组件中有事件响应、setTimeOut函数等。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选