我最近刚刚从 Angular 1 迁移到 Angular 4,我很难理解为什么组件属性更新时 DOM 没有更新。我搜索并阅读了无数帖子,但找不到任何似乎可以回答这个问题的内容。
我有一个应用程序,它有一个用于显示错误消息的组件,称为 MessageComponent:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'message',
templateUrl: './message.component.html',
styleUrls: ['./message.component.css']
})
export class MessageComponent implements OnInit {
messages: Array<string>;
constructor() {
}
ngOnInit() {
this.messages = ['My messages'];
}
/* Takes an array of messages */
showErrors(errors) {
this.messages = errors;
}
}
模板很简单:
<div class="message">
<p>Messages go here</p>
<div class="error">
<ul>
<li *ngFor="let message of messages">{{message}}</li>
</ul>
</div>
</div>
我正在从另一个组件调用
showErrors
方法:
import { Component, OnInit } from '@angular/core';
import { MessageComponent } from '../message/message.component';
@Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.css']
})
export class SignupComponent implements OnInit {
email: string;
password: string;
cardNumber: string;
expiryMonth: string;
expiryYear: string;
cvc: string;
plan: string;
constructor(private activatedRoute: ActivatedRoute, private auth: Auth, private message: MessageComponent) { }
signupUser() {
// do stuff here, then call back with status
}, (status: number, response: any) => {
if (status == 200) {
// yay, do success stuff
} else {
console.log('Error', response.error.message);
this.message.showErrors([response.error.message]);
}
});
}
从此表单调用
signupUser()
方法,即 signup.component.html
,SignupComponent 的模板:
<message></message>
<h1>Signup</h1>
<form (submit)="signupUser()">
<div class="row">
<div class="small-12 columns">
<label>Email address
<input type="text" [(ngModel)]="email" name="email">
</label>
</div>
</div>
<div class="row">
<div class="small-12 columns">
<label>Password
<input type="password" [(ngModel)]="password" name="password">
</label>
</div>
</div>
<div class="row">
<div class="small-12 columns">
<label>Card Number
<input type="text" [(ngModel)]="cardNumber" name="card-number" data-stripe="number">
</label>
</div>
</div>
<div class="row">
<div class="small-6 columns">
<label>Expiration Date (MM/YY)
<span><input type="text" size="2" [(ngModel)]="expiryMonth" name="expiry-month" placeholder="MM"><input type="text" size="2" [(ngModel)]="expiryYear" name="expiry-year" placeholder="YY"></span>
</label>
</div>
<div class="small-6 columns">
<label>CVC
<input type="text" [(ngModel)]="cvc" name="cvc">
</label>
</div>
</div>
<input type="submit" value="Sign Up">
</form>
希望这足以了解要点。我可以观察到,
this.messages
中的 MessagesComponent
在调用时确实会更改为正确的值,但是 DOM 不会更新。
我在这里缺少什么?我觉得我对 Angular 如何检测组件属性的更改并将其传播到 DOM 有一些根本性的误解,但我不知道我错过了什么。
感谢您的帮助!
我今天遇到了这个问题,我是这样解决的:
import { ChangeDetectorRef } from '@angular/core';
...它将每秒通知一次更改
constructor(private ref: ChangeDetectorRef){
setInterval(() => {
this.ref.detectChanges()
}, 1000);
}
...如果您只想通知其他人,您需要在需要后使用此行
this.ref.detectChanges()
我将按如下方式重新排列代码。整个想法是 MessageComponent 有一个 Input 属性,用于接收它必须显示的消息,并且 SignupComponent 使用模板绑定语法将错误消息传递给 MessageComponent。
消息组件
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'message',
templateUrl: './message.component.html',
styleUrls: ['./message.component.css']
})
export class MessageComponent implements OnInit {
@Input() messages: Array<string>; // Input property
constructor() {
}
ngOnInit() {
}
}
注册组件
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.css']
})
export class SignupComponent implements OnInit {
email: string;
password: string;
cardNumber: string;
expiryMonth: string;
expiryYear: string;
cvc: string;
plan: string;
messages: Array<string>; // property used to pass the messages to the MessageComponent
constructor(private activatedRoute: ActivatedRoute, private auth: Auth) { }
signupUser() {
// do stuff here, then call back with status
}, (status: number, response: any) => {
if (status == 200) {
// yay, do success stuff
} else {
console.log('Error', response.error.message);
this.messages = [response.error.message];
}
});
}
SignupComponent 模板
<!-- TEMPLATE BINDING -->
<message [messages]="messages"></message>
<h1>Signup</h1>
<form (submit)="signupUser()">
..... the rest of your code
</form>