但是,理想情况下,我需要另一种方式,例如 angular 1 $watch,因为还有其他方式可以更改我的复杂对象,而不仅仅是简单的输入字段
我在 Google Autocomplete 工作Component
,我正在处理类似的问题:当用户输入地址并从 Google 建议中选择一个时,我需要更新一些其他字段(如城市、省、邮政编码等)。
就像@Günter Zöchbauer说的那样,我创建了一个observable
以便知道我的 autocomplete 什么时候发生了变化component
,但第二个问题是发生这种情况时视图没有被更新。那是因为一个非常有趣和强大的东西叫做Zones。如果这个概念对您来说是新概念,请参阅此处和此处以获得很好的解释。
正如你可以在那里读到的,
应用程序状态变化是由三件事引起的:
事件 - 用户事件,例如点击、更改、输入、提交……</p>
XMLHttpRequests - 例如从远程服务获取数据时
定时器 - setTimeout(),setInterval(),因为 JavaScript
……事实证明,只有这些是 Angular 真正对更新视图感兴趣的情况。
因此,如果
还有其他方法可以更改我的复杂对象
您必须让 Angular 知道某些事情发生了变化,并且需要我们意识到更新的事情。这就是我所做的:
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
@Injectable()
export class AutocompleteService {
private autocompleteObserver: any;
public autocomplete: any;
constructor(...) {
this.autocompleteObserver = null;
this.autocomplete = Observable.create(observer => {
this.autocompleteObserver = observer;
});
}
public initializeAutocomplete(element): void {
// Where all the magic happens
// ...
// Send informtaion back to the caller
this.autocompleteObserver.next(addressInformation);
}
然后在我的页面中.ts
:
import { Component, NgZone } from '@angular/core';
import { AutocompleteService } from '../../providers/autocomplete-service/autocomplete-service';
@Component({
templateUrl: 'build/pages/my-new-page/my-new-page.html',
directives: [FORM_DIRECTIVES],
providers: [AutocompleteService]
})
export class MyNewPage {
constructor(..., private autocompleteService : AutocompleteService) {
// Initialize all the things you need
// ...
this.autocompleteService.autocomplete.subscribe((addressInfo) => {
this.ngZone.run(() => {
// Update the fields of the form, and Angular will update
// the view for you.
this.updateAddress(addressInfo);
});
});
}
}
所以通过在一个角度区域内执行一些代码,你告诉 Angular 它需要知道这些变化,因为事情可能需要更新。