在Angular 1中,创建一个用旋转器替换内容的加载指令相当容易,并且使用如下:
<div isLoading="$scope.contentIsLoading"></div>
其中contentHasLoaded是您在数据调用后在控制器中设置的简单布尔值。该指令本身很简单,大部分工作都是在模板中完成的:
<div class="spinner" ng-if="$scope.isLoading"></div>
<div ng-transclude ng-if="!$scope.isLoading"></div>
是否有&#34;清洁&#34;在Angular 2+中做到这一点的方法?通过清理我的意思是1)在Angular中,不使用vanilla JS直接操作DOM和2)可以作为现有元素的单个属性实现吗?
我确实认为这篇文章是后备:Image Loading Directive。但是,它比我想要的更冗长:使用常规组件需要我将所有异步内容包装在新标签中,而不是仅添加属性。
我真正想要的是结构指令中的东西(它应该是为#34;操纵DOM而设计的。&#34;)然而,我所见过的所有例子都是如此是* ngIf之类的重新创建,它隐藏内容但不插入新内容。具体而言,结构模板1)可以具有模板,或者2)插入组件或3)插入像<div class="spinner"></div>
这样简单的东西。到目前为止,这是我最好的尝试:
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[loading]',
inputs: ['loading']
})
export class LoadingDirective {
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef
) { }
@Input() set loading (isLoading: boolean) {
if (isLoading) {
this.viewContainer.clear();
// INSERT A COMPONENT, DIV, TEMPLATE, SOMETHING HERE FOR SPINNER
} else {
this.viewContainer.clear();
// If not loading, insert the original content
this.viewContainer.createEmbeddedView(this.templateRef);
}
}
}
答案 0 :(得分:8)
这可以在Angular2 +以您描述的方式完成,您走在正确的轨道上。您的结构指令将包含主机元素的模板,您可以注入一个组件来容纳加载图像等。
<强>指令强> 该指令采用输入参数来指示加载状态。每次设置此输入时,我们都会清除viewcontainer,并根据加载值注入加载组件或主机元素的模板。
@Directive({
selector: '[apploading]'
})
export class LoadingDirective {
loadingFactory : ComponentFactory<LoadingComponent>;
loadingComponent : ComponentRef<LoadingComponent>;
@Input()
set apploading(loading: boolean) {
this.vcRef.clear();
if (loading)
{
// create and embed an instance of the loading component
this.loadingComponent = this.vcRef.createComponent(this.loadingFactory);
}
else
{
// embed the contents of the host template
this.vcRef.createEmbeddedView(this.templateRef);
}
}
constructor(private templateRef: TemplateRef<any>, private vcRef: ViewContainerRef, private componentFactoryResolver: ComponentFactoryResolver) {
// Create resolver for loading component
this.loadingFactory = this.componentFactoryResolver.resolveComponentFactory(LoadingComponent);
}
}
<强>组件强> 你可以看到除了保留模板之外别无其他。
@Component({
selector: 'app-loading',
template: `<div class="loading">
<img src="assets/loading.svg" alt="loading">
</div>`
})
export class LoadingComponent {
constructor() { }
}
<强>实施强> 结构指令的用法,绑定到布尔值
<div *apploading="isLoadingBoolean">
<h3>My content</h3>
<p>Blah.</p>
</div>
注意:您还需要在ngModule的entryComponents数组中包含LoadingComponent。