我需要有关如何使可观察变量currentShop
依赖于变量shopList
的建议。
AppComponent
通过shopList
读取shopProvider
。它没有问题,但我需要修改代码以从加载的商店设置currentShop
。
感谢。
AppComponent:
export class AppComponent {
currentShop;
shopList;
constructor(router: Router,shopProvider:ShopProvider){
this.shopList = shopProvider.shops;
this.currentShop = shopProvider.currentShop;
shopProvider.loadShops();
shopProvider.setCurrentShop(-1);
router.navigate(['/System']);
}
}
ShopProvider:
export class ShopProvider{
private _http:Http;
shops:Observable<Array<Shop>>;
currentShop:Observable<Shop>;
private obServer:any;
private _shopDataStore : {
shops: Array<Shop>
}
constructor(http:Http){
this._http = http;
this.shops = new Observable(observer => this.obServer = observer).share();
//this.currentShop = ??
this._shopDataStore = {shops: []};
}
setCurrentShop(shopId:number){
//Code ??
}
loadShops(){
this._http
.get('/services/shop/list')
.map(res => res.json())
.subscribe(data => {
this._shopDataStore.shops = data;
this.obServer.next(this._shopDataStore.shops);
})
}
}
HTML:
<div>{{currentShop.name | async}}</div>
<ul>
<li *ngFor="#shop of shopList | async">
<a [routerLink]="['/Shop', {shopId: shop.id}]">
<span>{{shop.name}}</span>
</a>
</li>
</ul>
答案 0 :(得分:3)
我会选择更类似的架构:
<强> ShopService 强>
class Shop {
constructor(public shopId: Number, public shopName: string) {}
}
@Injectable()
class ShopService {
shops: Observable<Array<Shop>> = new Observable<Array<Shop>>();
shopId: Subject<Number> = new Subject<Number>();
currentShop: Observable<Shop> = new Observable<Shop>();
public static getShopById(shops: Array<Shop>, shopId: Number): Shop {
return shops.filter(shop => shop.shopId === shopId)[0];
}
public static compareShops(oldShop: Shop, newShop: Shop): Boolean {
return oldShop.shopId === newShop.shopId;
}
constructor(@Inject(Http) private http: Http) {
this.shops = this.http
.get('**url here**')
.map(res => res.json().shops);
this.currentShop = this.shops
.combineLatest(this.shopId, ShopService.getShopById)
.distinctUntilChanged(ShopService.compareShops);
}
setCurrentShop(shopId: Number): void {
this.shopId.next(shopId);
}
}
Component
中的用法:
ShopService.currentShop
保存到Component
中的变量(让我们说this.currentShop
{{ currentShop | async }}
或.subscribe()
用于ShopService.currentShop
观察,以便在商店发生变化时获得商店查看CodePen上的工作示例。我更喜欢这种方法,因为我没有保存任何状态,这似乎更符合反应式编程。
答案 1 :(得分:1)
我建议如下:
<强> ShopProvider 强>
private shopsObserver:Observer<Shop[]>;
private currentShopObserver: Observer<Shop>;
private _shopDataStore : {
shops: [],
currentShop: undefined
}
constructor(http:Http){
this._http = http;
this.shops = new Observable(observer => this.obServer = observer).share();
this.currentShop = new Observable(observer => this.shopObserver = observer).share();
}
setCurrentShop(shopId:number){
var item = this._shopDataStore.shops.find(item=>item.shopId == shopId);
this._shopDataStore.currentShop = item;
this.currentShopObserver.next(this._shopDataStore.currentShop);
}
loadShops(){
this._http
.get('/services/shop/list')
.map(res => res.json())
.subscribe(data => {
this._shopDataStore.shops = data;
this.shopsObserver.next(this._shopDataStore.shops);
})
}
<强> AppComponent 强>
export class AppComponent {
currentShop;
shopList;
constructor(router: Router,shopProvider:ShopProvider){
shopProvider.shops.subscribe(shops=>this.shopList = shops);
shopProvider.currentShop.subscribe(currentShop => this.currentShop = currentShop);
shopProvider.loadShops();
shopProvider.setCurrentShop(-1);
router.navigate(['/System']);
}
}
<强> HTML 强>
<div>{{currentShop?.name}}</div>
<ul>
<li *ngFor="#shop of shopList">
<a [routerLink]="['/Shop', {shopId: shop.id}]">
<span>{{shop.name}}</span>
</a>
</li>
</ul>