2017-06-26 85 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陣列英寸