ionic2+Angular 依赖注入之Subject ——使用Subject来实现组件之间的通信
在Angular+ionic2 开发过程中,我们不难发现,页面之间跳转之后返回时是不会刷新数据的。
场景一:当前页面需要登录之后才能获取数据——去登录,登录成功之后返回——页面需要手动刷新才能获取到数据。
场景二:当前正在浏览地址列表——选择添加或者更改现有地址,保存成功之后——返回列表,页面数据不是最新的数据。
……
实现需求:一旦用户登录成功,列表数据发生变化……就通知相关的组件,主动去获取最新的数据。
类似的场景有很多,在Angular开发中我们就需要使用Subject来实现组件之间的通信。
step1:创建主题对象。为了便于维护和管理,我把项目中需要通信的对象统一声明在一个文件中。
import { UserModel } from '../model-res/user-model';
import { Subject } from "rxjs/Rx";
export const AppOnChangeSunject = {
UserOnChange: new Subject<UserModel>(),//订阅用户登录状态的变化
OrderAddressOnChange:new Subject<any>(),//订阅订单地址是否发生改变
AddressListOnChange:new Subject<any>(),//订阅地址列表数据的更新
}
step2:在相关的数据更新接口中调用next()方法,通知相关的订阅者已经接受到新的信息,以地址列表为例。
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { URLService } from '../../common/urls';
import { EditAddressModel } from '../../model-req/edit-address-model';
import { AppOnChangeSunject } from '../../common/change-subject';
@Injectable()
export class JfAddressService {
constructor(private http: Http, private us: URLService) { }
getUserAddress(): Observable<any> {
let url = this.us.getUrl('yxt_getUserAddress')
return this.http.get(url).map(res => res.json().data);
}
deleteUserAddress(obj): Observable<any> {
// 删除地址
let url = this.us.getUrl('yxt_deleteUserAddress', obj);
return this.http.delete(url, obj).map(res => {
AppOnChangeSunject.AddressListOnChange.next(200);
return res.json();
})
}
editUserAddress(obj: EditAddressModel): Observable<any> {
// 编辑更新地址
let url = this.us.getUrl('yxt_editUserAddress', obj);
var data = this.us.objectToUrlParams(obj);
return this.http.put(url, data).map(res => {
AppOnChangeSunject.AddressListOnChange.next(200);
return res.json();
})
}
addUserAddress(obj: EditAddressModel): Observable<any> {
// 添加地址
let url = this.us.getUrl('yxt_addUserAddress', obj);
var data = this.us.objectToUrlParams(obj);
return this.http.post(url, data).map(res => {
AppOnChangeSunject.AddressListOnChange.next(200);
return res.json();
})
}
setUserDefaultAddress(obj):Observable<any>{
// 设为默认地址
let url=this.us.getUrl('yxt_setUserDefaultAddress',obj);
return this.http.post(url,null).map(res=>{
AppOnChangeSunject.AddressListOnChange.next(200);
return res.json();
})
}
}
以上的所有操作都会让地址列表的数据发生变化,所以在操作完相关操作之后需要发出通知。
step3:在地址列表组件中添加订阅。
import { Component, OnInit } from '@angular/core';
import { IonicPage, NavController, NavParams, AlertController } from 'ionic-angular';
import { JfAddressService } from '../jf-address.service';
import { AppOnChangeSunject } from '../../../common/change-subject';
import { MsgBarService } from '../../../common/msg-bar';
import { MainPage } from '../../../common/main';
import { WechatService } from '../../../common/wechat.service';
@IonicPage({
name: 'jfAddress',
segment: 'jfAddress/:p0',
defaultHistory:['usercenter']
})
@Component({
selector: 'page-jf-address',
templateUrl: 'jf-address.html',
})
//p0订单已选地址
export class JfAddressPage extends MainPage implements OnInit {
addresses: any[];
currentAddress;
constructor(
public navCtrl: NavController,
public navParams: NavParams,
private service: JfAddressService,
private alertCtrl: AlertController,
private ms: MsgBarService,
public wechat: WechatService) {
super(wechat);
this.currentAddress = navParams.data.p0 || '';
AppOnChangeSunject.AddressListOnChange.subscribe(res => {
if (res == 200) {
this.getUserAddress();//重新获取最新的数据
}
})
}
ngOnInit() {
this.getUserAddress();
}
getUserAddress(e?) {
this.service.getUserAddress().subscribe(res => {
if (res.addressWsDTOList) {
this.addresses = res.addressWsDTOList;
}
if (e) { e.complete(); }
},()=>{
if (e) { e.complete(); }
})
}
}
over!
【富潤屋,徳潤身】