Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 具有可观察异步管道问题的角度模板绑定_Angular_Rxjs_Rxjs6_Rxjs Observables - Fatal编程技术网

Angular 具有可观察异步管道问题的角度模板绑定

Angular 具有可观察异步管道问题的角度模板绑定,angular,rxjs,rxjs6,rxjs-observables,Angular,Rxjs,Rxjs6,Rxjs Observables,注意我在 模板: {{insuredType}} 投保类型$定义: @NeedsElement(sp(115621)、ap(116215)) 保险类型$():可观察{ 返回空(); } NeedsElementdecorator: 导出函数NeedsElement(…映射:NeedsElementMapping[]){ if(mappings.length==0){ 抛出新错误(“预期需要映射”); } 让lookup=newmap(); mappings.forEach((映射)=>{

注意我在

模板:


{{insuredType}}
投保类型$
定义:

@NeedsElement(sp(115621)、ap(116215))
保险类型$():可观察{
返回空();
}
NeedsElement
decorator:

导出函数NeedsElement(…映射:NeedsElementMapping[]){
if(mappings.length==0){
抛出新错误(“预期需要映射”);
}
让lookup=newmap();
mappings.forEach((映射)=>{
lookup.set(mapping.productId,mapping.elementId);
});
return(target:any,propertyKey:string,descriptor:PropertyDescriptor)=>{
descriptor.value=函数(…参数:任意[]){
Logger.info(“BBB”);
让实体=uEntityStoreContext.currentEntity;
设productId=entity['productId'];
如果(!productId){
抛出新错误(`无法从主机实体获取产品Id:${entity.ucId}`);
}
let elementId:number=lookup.get(实体['productId']);
如果(!elementId){
抛出新错误(`productId${productId}`无法定位需要元素ID`);
};
让entitystore=UcEntityStoreContext.current;
让entityApi=enitityStore.apiService作为QuotePolicyApiBase

如果它去了这个分支:

然后它继续向后端服务发送请求,绑定从不输出任何内容:

如果它是一个异步可观测项,那么它看起来总是会不断尝试评估可观测项,而不会结束,比如:


于2020年5月14日更新

我从你那里得到了答案


最后,我将方法Decorator更改为Property Decorator并发出fixed。

当您使用
insuredType$()| async
时,这意味着angular将在每次发生更改检测时调用此函数。因此,它也会每次调用
needsDefApi.fetchOne(productId,elementId)

为了避免这种情况,您需要将组件
标记为OnPush
。实际上,什么是lifehack以减少调用量,因为只有在组件的输入或触发输出发生更改时才会调用它。如果这种情况经常发生,则不会有帮助

或者您需要重新构造装饰器,以便在对相同的
实体的任何调用中返回相同的
可观察的
,因此
实体?.ext.insuredDetails.insuredType$()==实体?.ext.insuredDetails.insuredType$()
将为true

不确定是否有效,但应与之类似:

导出函数NeedsElement(…映射:NeedsElementMapping[]){
if(mappings.length==0){
抛出新错误(“预期需要映射”);
}
让lookup=newmap();
mappings.forEach((映射)=>{
lookup.set(mapping.productId,mapping.elementId);
});
Logger.info(“BBB”);
让实体=uEntityStoreContext.currentEntity;
设productId=entity['productId'];
如果(!productId){
抛出新错误(`无法从主机实体获取产品Id:${entity.ucId}`);
}
let elementId:number=lookup.get(实体['productId']);
如果(!elementId){
抛出新错误(`productId${productId}`无法定位需要元素ID`);
};
让entitystore=UcEntityStoreContext.current;
让entityApi=enitityStore.apiService作为QuotePolicyApiBase;
让needsDefApi=NeedsDefinitionApi.instance;
const stream$=needsDefApi.fetchOne(productId,elementId).pipe(
海图(
nd=>{
返回entityApi.fetchNeedsElementValue(entity.ucId,elementId).pipe(
concatMap(needsVal=>{
如果(!needsVal){
返回(“”);
}
if(nd.lookupId){
返回LookupApi.instance.getByPrimaryValueId(nd.lookupId,needsVal).pipe(
映射(res=>res.primaryValue)
);
}否则{
归还(needsVal);
}
})
)
}
)
);
return(target:any,propertyKey:string,descriptor:PropertyDescriptor)=>{
descriptor.value=函数(…参数:任意[]){
返回流$;//从

解决方案是使用属性装饰器而不是方法装饰器,因此insuredType$现在是:

@NeedsElement(sp(115623)、ap(116215))
只读保险类型$:可观察;
装饰师现在在

导出函数NeedsElement(…映射:NeedsElementMapping[]){
...
const observable=of('').pipe(开关映射(()=>{
...
})
return(target:any,propertyKey:string)=>{
常量getter=()=>{
可观测收益;
};
Object.defineProperty(target,propertyKey{
get:getter,
可枚举:正确,
对,,
});
};
}
注意必须定义返回函数之外的可观测值,否则它仍然会陷入无休止的循环,比如说以下代码不起作用:

导出函数NeedsElement(…映射:NeedsElementMapping[]){
...
return(target:any,propertyKey:string)=>{
常量getter=()=>{
返回('').pipe(开关映射(()=>{
...
});
};
Object.defineProperty(target,propertyKey{
get:getter,
可枚举:正确,
对,,
});
};
}

我从这里得到了答案:那你为什么不关闭/删除这个?这个有更多的上下文