2017-06-26 161 views
2

与微调更换装载量在1角,这是相当容易地创建一个加载指令,取代了微调的内容和使用,像这样:一个指令在角2+

<div isLoading="$scope.contentIsLoading"></div> 

凡contentHasLoaded是数据调用后在控制器中设置的简单布尔值。该指令本身很简单,大部分工作正在模板完成:

<div class="spinner" ng-if="$scope.isLoading"></div> 
<div ng-transclude ng-if="!$scope.isLoading"></div> 

是否有一个“干净”的方式在角2+做到这一点?通过干净的我的意思是1)Angular内,不使用香草JS直接操作DOM和2)可以实现为一个现有的元素的单一属性?

我的确看到这篇文章作为后备:Image Loading Directive。但是,它比我想要的要冗长一些:使用常规组件需要我将所有异步内容包装在新标签中,而不仅仅是添加属性。

我真正在寻找的是结构指令中的东西(它应该是为“操纵DOM”而设计的。)然而,我所看到的所有例子都是类似于* 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

嗨,如果你想我最近在一个项目中使用了一个指令来创建一些内容并应用一些类......它可能会帮助你:https://github.com/damnko/angular2-django- movies/blob/master/angular2-client/src/app/user/components/input-hint.component.ts – crash

+0

你应该如何应用该指令?显示一些html –

+0

那么,我确实指定了一个属性,我确实给出了我从角度知道的例子。如果我知道Angular 2中有这样的事情,我不会问这个问题,但我想像它会是类似

Normal content goes here
ansorensen

回答

3

这可以在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> 

注意:您还需要包括LoadingComponent在ngModule的entryComponents阵列英寸