Angular 使用数据转换创建指令
我想创建一个LoaderDirective,它获取并可观察到加载数据,同时显示一个微调器,加载时将微调器更改为原始数据,同时使用“as”关键字公开加载的数据 我想这样使用它:Angular 使用数据转换创建指令,angular,typescript,rxjs,angular-directive,Angular,Typescript,Rxjs,Angular Directive,我想创建一个LoaderDirective,它获取并可观察到加载数据,同时显示一个微调器,加载时将微调器更改为原始数据,同时使用“as”关键字公开加载的数据 我想这样使用它: 这就是我到目前为止所做的: @Directive({ // tslint:disable-next-line:directive-selector selector: '[load]', }) export class LoadDirective<T> { private data: T; @
这就是我到目前为止所做的:
@Directive({
// tslint:disable-next-line:directive-selector
selector: '[load]',
})
export class LoadDirective<T> {
private data: T;
@Input()
set load(observable: Observable<T>) {
observable.subscribe({
next: value => this.loaded(value),
error: error => this.showError(error)
});
}
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private componentFactoryResolver: ComponentFactoryResolver
) {
this.viewContainer.clear();
this.viewContainer.createComponent(this.componentFactoryResolver.resolveComponentFactory(SpinnerComponent));
}
private loaded(value: T) {
this.data = value;
this.viewContainer.clear();
this.viewContainer.createEmbeddedView(this.templateRef, {load: this.data});
}
private showError(e: string) {
this.viewContainer.clear();
const errorComponent = this.viewContainer.createComponent(this.componentFactoryResolver.resolveComponentFactory(ErrorComponent));
errorComponent.instance.error = e;
}
}
@指令({
//tslint:禁用下一行:指令选择器
选择器:“[load]”,
})
导出类装入指令{
私人资料:T;
@输入()
设定负荷(可观察:可观察){
可观察的({
下一步:value=>this.loaded(value),
error:error=>this.淋浴错误(error)
});
}
建造师(
私有templateRef:templateRef,
私有viewContainer:ViewContainerRef,
专用componentFactoryResolver:componentFactoryResolver
) {
this.viewContainer.clear();
this.viewContainer.createComponent(this.componentFactoryResolver.resolveComponentFactory(SpinnerComponent));
}
私有加载(值:T){
这个数据=值;
this.viewContainer.clear();
this.viewContainer.createEmbeddedView(this.templateRef,{load:this.data});
}
私人淋浴ROR(e:字符串){
this.viewContainer.clear();
const errorComponent=this.viewContainer.createComponent(this.componentFactoryResolver.resolveComponentFactory(errorComponent));
errorComponent.instance.error=e;
}
}
问题是输入数据是可观察的,因此它期望输出是可观察的。是否有类似的方法来改变这一点,例如管道处的
TransformPipe
?如何解决此问题?以下是我尝试过的方法,请告诉我是否有效
范例
只需对代码进行一点小修改
更改自
this.viewContainer.createEmbeddedView(this.templateRef, {load: this.data});
至
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
viewRef.context.data = this.data;
<div *appLoader="data$; data as result">
{{result | json}}
</div>
模板更改为
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
viewRef.context.data = this.data;
<div *appLoader="data$; data as result">
{{result | json}}
</div>
{{result}json}
我可以使用异步pip来实现这一点,但我发现如果我可以在指令内实现这一点,那么我可以通过将load()
重命名为loadFor()
然后像这样调用它来创建一个解决方法:
。我只是好奇:为什么你想创建一个指令而不是一个组件?我想做的是使用加载的可观察项(或可观察项),而不用手动订阅组件并编写所有样板文件。我认为如果我只使用异步管道和ngIf:
会更好。但是,如果我可以编写自己的指令来完成所有这些,跳过实现自己的异步管道,那么这是多余的:
。这让我可以在div中的任何地方使用项
,这是我想要的,没有用于订阅可观察项和存储结果的样板文件,没有额外的组件,非常漂亮和干净的代码,只订阅一次,结果就在范围内。第一个更改是多余的-更新的模板可以以任何方式工作。我正在考虑用data$之类的东西来解决问题;数据作为结果
,但不确定这是否符合问题的要求。