使用共享服务在angular2中进行更改检测
change detection in angular2 using shared service
我有一个 parent 函数 ngOnInit()
,它从 google 映射中获取值,如下所示
instance.input = document.getElementById('google_places_ac');
autocomplete = new google.maps.places.Autocomplete(instance.input, { types: ['(cities)']});
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace();
instance.setValue(place.address_components[3].long_name, place.address_components[2].long_name, place.address_components[1].long_name);
});
setValue()
是与共享服务共享价值的函数,在 html 页面上,我在 parent 和 child 上有相同的内容
<input id="google_places_ac" [(attr.state)]="state" [(attr.country)]="coutnry" name="google_places_ac" type="text" value="{{city}}" class="form-control" />
在 parent 组件 class 中,我在 setValue()
函数
上触发更改检测
setValue(a, b, c) {
this.coutnry = a;
this.state = b;
this.city = c;
this.sharedService.country = this.coutnry;
this.sharedService.city = this.city;
this.sharedService.state = this.state;
this.cdr.detectChanges();
// console.log(this.coutnry, this.state, this.city);
}
这在 parent 上运行良好,但在 child 上没有发生变化,我创建了一个点击功能,它在 child 上触发 changedetection,它也可以工作,但我希望它触发来自 parent 的自动更新是否有任何解决方法?
当涉及到在组件之间共享全局对象时,最好使用全局共享服务结合Rxjs
observable design pattern
。下面是代码,你应该根据你的配置:
首先,您的全球共享服务应如下所示:
import {Injectable} from "angular2/core";
import {Subject} from "rxjs/Subject";
@Injectable()
export class SearchService {
private _searchText = new Subject<string>();
public searchTextStream$ = this._searchText.asObservable();
broadcastTextChange(text:string) {
this._searchText.next(text);
}
}
其次,您将 service
注入 parent component
...
constructor(private _searchService:SearchService) {
...
第三,将服务添加到您的父组件或更高组件的providers
列表中,因为该服务在订阅的组件之间应该是相同的实例,这部分很重要:
providers: [SearchService,...]
然后当你想要 broadcast
新的改变时你调用 broadcastTextChange
新值如下:
...
this._searchService.broadcastTextChange("newTextHere");
...
然后在你的 the child component
中注入相同的 service
并订阅它:
this._searchService.searchTextStream$.subscribe(
text => {
// This text is a new text from parent component.
this.localText = text;
//Add your own logic here if you need.
}
)
我有一个 parent 函数 ngOnInit()
,它从 google 映射中获取值,如下所示
instance.input = document.getElementById('google_places_ac');
autocomplete = new google.maps.places.Autocomplete(instance.input, { types: ['(cities)']});
google.maps.event.addListener(autocomplete, 'place_changed', function () {
var place = autocomplete.getPlace();
instance.setValue(place.address_components[3].long_name, place.address_components[2].long_name, place.address_components[1].long_name);
});
setValue()
是与共享服务共享价值的函数,在 html 页面上,我在 parent 和 child 上有相同的内容
<input id="google_places_ac" [(attr.state)]="state" [(attr.country)]="coutnry" name="google_places_ac" type="text" value="{{city}}" class="form-control" />
在 parent 组件 class 中,我在 setValue()
函数
setValue(a, b, c) {
this.coutnry = a;
this.state = b;
this.city = c;
this.sharedService.country = this.coutnry;
this.sharedService.city = this.city;
this.sharedService.state = this.state;
this.cdr.detectChanges();
// console.log(this.coutnry, this.state, this.city);
}
这在 parent 上运行良好,但在 child 上没有发生变化,我创建了一个点击功能,它在 child 上触发 changedetection,它也可以工作,但我希望它触发来自 parent 的自动更新是否有任何解决方法?
当涉及到在组件之间共享全局对象时,最好使用全局共享服务结合Rxjs
observable design pattern
。下面是代码,你应该根据你的配置:
首先,您的全球共享服务应如下所示:
import {Injectable} from "angular2/core";
import {Subject} from "rxjs/Subject";
@Injectable()
export class SearchService {
private _searchText = new Subject<string>();
public searchTextStream$ = this._searchText.asObservable();
broadcastTextChange(text:string) {
this._searchText.next(text);
}
}
其次,您将 service
注入 parent component
...
constructor(private _searchService:SearchService) {
...
第三,将服务添加到您的父组件或更高组件的providers
列表中,因为该服务在订阅的组件之间应该是相同的实例,这部分很重要:
providers: [SearchService,...]
然后当你想要 broadcast
新的改变时你调用 broadcastTextChange
新值如下:
...
this._searchService.broadcastTextChange("newTextHere");
...
然后在你的 the child component
中注入相同的 service
并订阅它:
this._searchService.searchTextStream$.subscribe(
text => {
// This text is a new text from parent component.
this.localText = text;
//Add your own logic here if you need.
}
)