Angular 订阅中存在多个请求问题
我在我的组件上调用一个方法,该方法通过输入中输入的postalcode加载地址信息。 首先,我调用将信息加载到getAddress$变量中的方法,然后订阅它以获取数据并将其分配给表单输入。 在第一次页面加载时,它只执行api中的一个调用,但当我通知另一个postalcode时,我的subscribe将再添加一个return,对api进行多个调用。 我要做的是,对于输入的每个邮政编码,对于每个邮政编码只给我一个结果。 下面是我的代码,该方法在输入模糊事件时触发。 我已经实现了本文中包含的所有不成功的解决方案 你能帮我解决这个问题吗?我做错了什么 谢谢Angular 订阅中存在多个请求问题,angular,ngrx-store,ngrx-effects,Angular,Ngrx Store,Ngrx Effects,我在我的组件上调用一个方法,该方法通过输入中输入的postalcode加载地址信息。 首先,我调用将信息加载到getAddress$变量中的方法,然后订阅它以获取数据并将其分配给表单输入。 在第一次页面加载时,它只执行api中的一个调用,但当我通知另一个postalcode时,我的subscribe将再添加一个return,对api进行多个调用。 我要做的是,对于输入的每个邮政编码,对于每个邮政编码只给我一个结果。 下面是我的代码,该方法在输入模糊事件时触发。 我已经实现了本文中包含的所有不成功
// class CommonEffect
@Injectable()
export class CommonEffect {
constructor(private actions$: Actions,
private authApi: CommonService) {
}
@Effect()
getAddress$: Observable<Action> = this.actions$
.pipe(
ofType(actions.ActionTypes.GET_ADDRESS),
map((action: actions.GetAddress) => action.payload),
switchMap((state) => {
return this.authApi.getAddress(state)
.pipe(
map((address) => new actions.GetAddressSuccess(address)),
catchError(error => of(new actions.GetAddressFail(error)))
);
})
);
}
// function reducer
export function reducer(state = initialState, { type, payload }: any): CommonState {
if (!type) {
return state;
}
switch (type) {
case actions.ActionTypes.GET_ADDRESS:
{
return Object.assign({}, state, {
getAddressLoading: true,
getAddressLoaded: false,
getAddressFailed: false,
});
}
case actions.ActionTypes.GET_ADDRESS_SUCCESS: {
const tempAddress = new SearchAddressModel(payload.data);
return Object.assign({}, state, {
address: tempAddress,
getAddressLoading: false,
getAddressLoaded: true,
getAddressFailed: false,
});
}
case actions.ActionTypes.GET_ADDRESS_FAIL:
{
return Object.assign({}, state, {
getAddressLoading: false,
getAddressLoaded: true,
getAddressFailed: true,
});
}
default: {
return state;
}
}
}
// class CommonSandbox
@Injectable()
export class CommonSandbox {
/* get address*/
public getAddress$ = this.appState$.select(getAddress);
public addressLoading$ = this.appState$.select(addressLoading);
public addressLoaded$ = this.appState$.select(addressLoaded);
public addressFailed$ = this.appState$.select(addressFailed);
constructor(private router: Router,
protected appState$: Store<store.AppState>,
) {
}
public getAddress(params) : void {
this.appState$.dispatch(new commonAction.GetAddress(params));
}
}
// class component
export class AddaddressesComponent implements OnInit, OnDestroy {
addAddressForm: FormGroup;
addressId: any;
openAddress = false;
private subscriptions: Array<Subscription> = [];
constructor(private route: ActivatedRoute, private router: Router, public formBuilder: FormBuilder, public snackBar: MatSnackBar, public commonSandbox: CommonSandbox, public accountSandbox: AccountSandbox) {
}
ngOnInit() {
this.addressId = this.route.snapshot.paramMap.get('id');
this.addAddressForm = this.formBuilder.group({
'firstName': ['', Validators.required],
'lastName': ['', Validators.required],
'address': ['', Validators.required],
'phoneNumber': '',
'phoneMobileNumber': ['', Validators.required],
'complement': '',
'reference': '',
'addresstype': '',
'city': ['', Validators.required],
'zone': ['', Validators.required],
'state': ['', Validators.required],
'postalcode': ['', Validators.required]
});
this.addAddressForm.patchValue({ addresstype: '1', tc: true });
}
// method (blur) search address for postalcode
public getSeacrhAddress(value: any) {
if (value) {
// Here I call the api that returns the address according to the postalcode entered, below I retrieve the value through subscribe.
this.commonSandbox.getAddress(value.replace(/[^\d]+/g, ''));
// the subscribe address parameter in the first pass on the first page load is undefined, as I inform another postalcode it always has the previous value
this.subscriptions.push(this.commonSandbox.getAddress$.subscribe(address => {
//With the breakpoint here, each postalcode you enter will increment one more pass instead of just once.
if (address) {
this.addAddressForm.controls['address'].setValue(address.logradouro);
this.addAddressForm.controls['city'].setValue(address.localidade);
this.addAddressForm.controls['zone'].setValue(address.bairro);
this.addAddressForm.controls['state'].setValue(address.uf);
this.openAddress = true;
}
}));
}
}
// destroy the subscribed events while page destroy
ngOnDestroy() {
this.subscriptions.forEach(each => {
each.unsubscribe();
});
}
}
//类CommonEffect
@可注射()
出口类共同效应{
构造函数(私有操作$:操作,
私有authApi:CommonService){
}
@效果()
getAddress$:Observable=this.actions$
.烟斗(
ofType(actions.ActionTypes.GET_ADDRESS),
map((action:actions.GetAddress)=>action.payload),
开关映射((状态)=>{
返回此.authApi.getAddress(状态)
.烟斗(
映射((地址)=>newactions.GetAddressSuccess(地址)),
catchError(error=>of(new actions.GetAddressFail(error)))
);
})
);
}
//功能减速机
导出函数缩减器(state=initialState,{type,payload}:any):CommonState{
如果(!类型){
返回状态;
}
开关(类型){
case actions.ActionTypes.GET_地址:
{
返回Object.assign({},state{
getAddressLoading:true,
getAddressLoaded:false,
getAddressFailed:false,
});
}
案例操作.ActionTypes.GET_ADDRESS_成功:{
const tempAddress=新的SearchAddressModel(payload.data);
返回Object.assign({},state{
地址:tempAddress,,
getAddressLoading:false,
getAddressLoaded:true,
getAddressFailed:false,
});
}
案例操作.ActionTypes.GET\u ADDRESS\u失败:
{
返回Object.assign({},state{
getAddressLoading:false,
getAddressLoaded:true,
getAddressFailed:true,
});
}
默认值:{
返回状态;
}
}
}
//类CommonAndBox
@可注射()
导出类CommonAndBox{
/*获取地址*/
public getAddress$=this.appState$.select(getAddress);
public addressLoading$=this.appState$.select(addressLoading);
public addressLoaded$=this.appState$.select(addressLoaded);
public addressFailed$=this.appState$.select(addressFailed);
构造函数(专用路由器:路由器、,
受保护的appState$:存储,
) {
}
公共getAddress(参数):无效{
this.appState$.dispatch(新的commonAction.GetAddress(params));
}
}
//类组件
导出类addAddressComponent实现OnInit、OnDestroy{
addAddressForm:FormGroup;
地址ID:任何;
openAddress=false;
私有订阅:数组=[];
构造函数(私有路由:ActivatedRoute,私有路由器:router,公共formBuilder:formBuilder,公共snackBar:Matsnakbar,公共CommonAndBox:CommonAndBox,公共帐户Sandbox:accountSandbox){
}
恩戈尼尼特(){
this.addressId=this.route.snapshot.paramMap.get('id');
this.addAddressForm=this.formBuilder.group({
“firstName”:[“”,验证器。必需],
“lastName”:[“”,验证器。必需],
“地址”:['',验证器。必需],
“电话号码”:“,
'phoneMobileNumber':['',验证器。必需],
“补语”:“,
'参考':'',
“地址类型”:“,
“城市”:['',验证器。必需],
“区域”:[“”,验证器。必需],
“状态”:['',验证器。必需],
“postalcode”:['',验证器。必需]
});
这个.addAddressForm.patchValue({addresstype:'1',tc:true});
}
//postalcode的方法(模糊)搜索地址
公共GetSeaCrhadAddress(值:任意){
如果(值){
//这里我调用api,它根据输入的postalcode返回地址,下面我通过subscribe检索值。
this.commonSandbox.getAddress(value.replace(/[^\d]+/g',);
//在第一次页面加载的第一个过程中,subscribe address参数是未定义的,因为我通知另一个postalcode它始终具有先前的值
this.subscriptions.push(this.commonSandbox.getAddress$).subscripte(address=>{
//使用此处的断点,您输入的每个postalcode将增加一次而不是一次。
如果(地址){
这个.addAddressForm.controls['address'].setValue(address.logradouro);
这个.addAddressForm.controls['city'].setValue(address.localidade);
这个.addAddressForm.controls['zone'].setValue(address.bairro);
这个.addAddressForm.controls['state'].setValue(address.uf);
this.openAddress=true;
}
}));
}
}
//在页面销毁时销毁订阅的事件
恩贡德斯特罗(){
this.subscriptions.forEach(每个=>{
每个。取消订阅();
});
}
}
take(1)
应该有效,但放在哪里很重要。
我没有测试以下代码,但我认为这将适用于您:
@Effect()
getAddress$: Observable<Action> = this.actions$
.pipe(
ofType(actions.ActionTypes.GET_ADDRESS),
take(1),
map((action: actions.GetAddress) => action.payload),
switchMap((state) => {
return this.authApi.getAddress(state)
.pipe(
take(1)
map((address) => new actions.GetAddressSuccess(address)),
catchError(error => of(new actions.GetAddressFail(error)))
);
})
);
@Effect()
getAddress$:Observable=this.actions$
.烟斗(
ofType(actions.ActionTypes.GET_ADDRESS),
ngOnInit() {
this.addressId = this.route.snapshot.paramMap.get('id');
this.addAddressForm = this.formBuilder.group({
'firstName': ['', Validators.required],
'lastName': ['', Validators.required],
'address': ['', Validators.required],
'phoneNumber': '',
'phoneMobileNumber': ['', Validators.required],
'complement': '',
'reference': '',
'addresstype': '',
'city': ['', Validators.required],
'zone': ['', Validators.required],
'state': ['', Validators.required],
'postalcode': ['', Validators.required]
});
this.addAddressForm.patchValue({ addresstype: '1', tc: true });
// the subscribe address parameter in the first pass on the first page load is undefined, as I inform another postalcode it always has the previous value
this.subscriptions.push(this.commonSandbox.getAddress$.subscribe(address => {
//With the breakpoint here, each postalcode you enter will increment one more pass instead of just once.
if (address) {
this.addAddressForm.controls['address'].setValue(address.logradouro);
this.addAddressForm.controls['city'].setValue(address.localidade);
this.addAddressForm.controls['zone'].setValue(address.bairro);
this.addAddressForm.controls['state'].setValue(address.uf);
this.openAddress = true;
}
}));
}
// method (blur) search address for postalcode
public getSeacrhAddress(value: any) {
if (value) {
// Here I call the api that returns the address according to the postalcode entered, below I retrieve the value through subscribe.
this.commonSandbox.getAddress(value.replace(/[^\d]+/g, ''));
}
}