2017-07-24 7 views
0

Ich habe ein Verhaltensthema erstellt, das ich verwende, um ein Symbol zum Laden eines Drehfelds in meiner Anwendung zu aktivieren.Angular 2 - Mehrere Parameter mit Verhaltensfach?

Service:

// Observe our loader status 
public loaderStatus: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); 

/** 
* Toggle the loading indicator status 
* @param value 
*/ 
displayLoader(value: boolean) { 
    this.loaderStatus.next(value); 
} 

Komponente:

this._massEmpService.displayLoader(true); // Toggle true/false 

HTML:

<div *ngIf="objLoaderStatus" class="loader" align="center"> 
    <img src="images/loading-bars.svg" alt="" /> 
</div> 

Während dies funktioniert gut für Wenn ich diesen Spinner in mehreren Bereichen über meine Anwendung verwenden möchte, ist die Funktion zu breit und würde alle Spinner-Instanzen in der App auslösen, wenn mehrere Spinner auf derselben Seite vorhanden wären.

Meine Frage:

Ist es möglich, ein Objekt oder mehrere params zu einem Verhalten unterliegt geben, so dass ich nicht nur steuern, ich kann passieren kann den enabled/disabled Status, sondern auch ein Element ID eines bestimmten Typs so die Spinner möchte ich zeigen.

Beispiel Ziel:

<div *ngIf="objLoaderStatus && spinnerID == 'home'" class="loader" align="center"> 
    <img src="images/loading-bars.svg" alt="" /> 
</div> 

<div *ngIf="objLoaderStatus && spinnerID == 'search'" class="loader" align="center"> 
    <img src="images/loading-bars.svg" alt="" /> 
</div> 

Function Call:

this._massEmpService.displayLoader(true, 'search'); 

Was ist der beste Weg, dies zu tun zu gehen? Muss ich ein zweites Verhaltensthema machen, nur um die elementID des Spinners zu halten, die ich referenzieren möchte?

Antwort

1

Wenn Sie mehrere Spinner auf der gleichen Seite verwenden möchten, würde ich lieber eine strukturelle Anweisung oder eine Spinner-Komponente für diesen Zweck verwenden. Siehe die xample unten: -

Angular img loading directive

Angular2: progress/loading overlay directive

+0

Vielen Dank für die Antwort. Ich verstehe nicht, wie das anders ist als das, was ich habe. Sie haben eine Komponente, die Abschnitte auf ihrer Seite umschließt. Diese Komponente erhält eine Prop, die es aktiviert/deaktiviert, was ich im Wesentlichen mit einer Eigenschaft mache und 'ngIf' verwende. Der Teil, der mich verwirrt, ist, wie man spezifisch sagt, welche ich umschalten möchte, wenn ich mit mehreren Instanzen von Ladespinnereien klarkomme. – SBB

+0

@SBB, es ist eher eine Trennung von Interesse. Service hat eine globale Reichweite. Solange Sie den Spinner für die ganze Seite verwenden, ist es großartig. Wenn Sie mehrere Komponenten mit Spinner für jede von ihnen haben, wäre eine strukturelle Anweisung sinnvoll. Es wird automatisch ausgeblendet/zerstört, wenn die Komponente, auf der es angewendet wird, ausgeblendet ist. Das ElementRef in der Direktive gibt das Element an, auf das es angewendet wurde. So können Sie bei Bedarf alle dom-Eigenschaften des Elements abrufen. Sie können die Bedingung übergeben, um spinner als Eingabe für die Anweisung anzuzeigen. Ich werde versuchen, meine Antwort mit z. B. –

+0

zu aktualisieren. Es klingt, als könnte es meine Situation passen, nur hatte es eine harte Zeit, das von den verlinkten Seiten zu sammeln. Wenn die Zeit es erlaubt und Sie ein besseres Beispiel haben, würde ich es gerne hören und dies als meine einmal implementierte Lösung akzeptieren. – SBB

0

mehrere Parameter in Ihrem BehaviorSubject verwenden möchten, können Sie eine neue Klasse erstellen, um die Parameter zu halten.
Ich hatte fast genau den gleichen Anwendungsfall mit einem Loader-Icon, wo meine App in TS für Angular 4 geschrieben ist, aber ich wollte eine Client-API in JS für Plugins verfügbar machen.
Sie können hier mehr über die Implementierung sehen -
https://github.com/savantly-net/sprout-platform/tree/development/web/sprout-web-ui/src/app/client-api

Loader Optionen Definition -

export class LoaderOptions { 
    key: string; 
    element: Element 
} 

Im Service -

showLoaderBehavior = new BehaviorSubject<LoaderOptions>(null); 
    hideLoaderBehavior = new BehaviorSubject<LoaderOptions>(null); 

    showLoader(options: LoaderOptions) { 
    this.zone.run(() => this.showLoaderBehavior.next(options)); 
    } 

    hideLoader(options: LoaderOptions) { 
    this.zone.run(() => this.hideLoaderBehavior.next(options)); 
    } 

in der Komponente Implementierung -

... 
    showLoader = function (options: LoaderOptions) { 
    if (options == null) { 
     return; // probably just initialized, so return silently 
    } 
    if (!options.key) { 
     throw new Error('A key is required to show the loader, so that it may be removed with the same key.'); 
     } 
     const defaultElement = document.querySelector('my-client-api'); 
     options.element = options.element || defaultElement; 

     const imgWrapper = document.createElement('div'); 
     imgWrapper.setAttribute('id', options.key); 
     imgWrapper.setAttribute('style', 'text-align:center;'); 

     const imgElement = document.createElement('img'); 
     imgElement.setAttribute('style', 'width:200px;'); 
     imgElement.setAttribute('src', './img/loader.svg'); 

     imgWrapper.appendChild(imgElement); 
     options.element.appendChild(imgWrapper); 
    }; 

    hideLoader = function (options: LoaderOptions) { 
    if (options == null) { 
     return; // probably just initialized, so return silently 
    } 
    if (!options.key) { 
     throw new Error('A key is required to remove the loader'); 
    } 
    const imgWrapper = document.querySelector('div#' + options.key); 
    imgWrapper.remove(); 
    }; 

    ngAfterViewInit() { 
    this.sproutApi.toastSubject.subscribe(options => this.handleToast(options)); 
    this.sproutApi.showLoaderBehavior.subscribe(options => this.showLoader(options)); 
    this.sproutApi.hideLoaderBehavior.subscribe(options => this.hideLoader(options)); 
    } 
    ... 

JS Plugin mit der api -

<script type="text/javascript"> 
    function Shack() { 

     var processInfoElement = document.querySelector('.shack-processes'); 

     this.loadProcessInfo = function(){ 
      var loaderKey = 'pLoader'; 
      sprout.showLoader({key: loaderKey}); 
      sprout.zone.run(function(){ 
       sprout.http.get('./rest/modules/shack/processes', {responseType: 'text'}).subscribe(function(response){ 
        processInfoElement.innerHTML = response; 
        sprout.hideLoader({key: loaderKey}); 
       }); 
      }); 
     }; 


    } 
    window.shack = new Shack(); 
</script>