2017-05-18 2 views
19

Bevor ich selbst eine Lösung implementiere, würde ich gerne wissen, ob es eine einfache Möglichkeit gibt, den Stil eines Elements (ein kurzes Highlight) zu ändern, wenn sich der Wert der Datengebundenen Eigenschaft gerade geändert hat.Angular: Wie können Sie gerade geänderte Dom-Elemente vorübergehend markieren?

Es gibt viele Elemente in meinem DOM, also möchte ich nicht eine dedizierte Eigenschaft in der Komponente speichern und pflegen.

Meine Elemente hervorzuheben traditionelle Elemente der Eingabemaske:

<tr field label="Lieu dépôt"> 
     <select class="cellinput" #lieuDepotBon [(ngModel)]="rapport.LieuDepotBon" (ngModelChange)="changeRapport({LieuDepotBon:$event})"> 
      <option [ngValue]="null"></option> 
      <option [ngValue]="i" *ngFor="let depotBonChoice of DepotBonInterventionValues; let i = index">{{DepotBonIntervention[i]}}</option> 
     </select> 
    </tr> 
    <tr field *ngIf="rapport.LieuDepotBon==DepotBonIntervention.Autre" label="Autre lieu"> 
     <input class="cellinput" #autreLieuDepotBon [(ngModel)]="rapport.AutreLieuDepotBon" (ngModelChange)="changeRapport({AutreLieuDepotBon:autreLieuDepotBon.value})" /> 
    </tr> 

ich über Sonderklasse Stile festlegen, von Angular2 auf Element mit ngModel Richtlinie gehört dabei helfen könnte, was ich brauche, aber ich konnte nicht mehr darüber finden .

+2

ist diese Frage nur spezifisch für 'input' Elemente? und was meinst du mit "verändert"? _Ich habe von speziellen Klassenstilen gehört, die von Angular2_ gesetzt wurden - meinst du "ng-dirty" -Klasse? Wenn ja, versuchen Sie einfach, einen Stil für 'input.ng-dirty {background-color: green}' –

+0

hinzuzufügen. Dies ist spezifisch für Elemente mit einer ngModel-Direktive. Es scheint, dass ng-dirty/ng-touched keine Lösung bietet, da sie von der Aktion eines Benutzers auf dem Steuerelement abhängen. In meinem Fall werden Änderungen nicht vom Benutzer vorgenommen. Es ist nur eine Veränderung im Datenmodell. – abreneliere

+1

_In meinem Fall werden Änderungen nicht vom Benutzer durchgeführt._ - Können Sie ein Beispiel zeigen? –

Antwort

0

Hier ist meine Lösung.

Ich wollte die Daten im Formular hervorheben, die von anderen Benutzern in Echtzeit geändert werden.

In meinem HTML-Formular ersetzte ich native HTML-Elemente durch eckige Komponenten. Für jede Art von nativem Element habe ich eine neue Angular Component mit Highlight-Unterstützung erstellt. Jede Komponente implementiert die ControlValueAccessor Angular-Schnittstelle.

In der Stammform I das native Element ersetzt:

<input [(ngModel)]="itinerary.DetailWeather" /> 

durch mein benutzerdefiniertes Element:

<reactive-input [(ngModel)]="itinerary.DetailWeather"></reactive-input> 

Wenn Angular Anrufe detectChanges() für das übergeordnete Formular, es läßt Sie die Daten, die von den Komponenten des Formulars als Eingaben verwendet werden. Wenn eine Komponente ein ControlValueAccessor ist und eine Änderung im Anwendungsmodell aufgetreten ist, ruft sie die Methode ControlValueAccessor auf. writeValue (Wert). Dies ist die Methode, die aufgerufen wird, wenn sich die Daten im Speicher geändert haben. Ich benutze es als einen Haken, um vorübergehend den Stil zu aktualisieren, um das Highlight hinzuzufügen.

Hier ist das benutzerdefinierte Element. Ich habe Angular Animations zum Aktualisieren der Rahmenfarbe und zum Zurückblenden auf die ursprüngliche Farbe verwendet.

import { Component, Input, forwardRef, ChangeDetectorRef } from '@angular/core'; 
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; 
import { trigger, state, style, animate, transition, keyframes } from '@angular/animations'; 

@Component(
{ 
    selector: 'reactive-input', 
    template: `<input class="cellinput" [(ngModel)]="value" [@updatingTrigger]="updatingState" />`, 
    styles: [`.cellinput { padding: 4px }`], 
    animations: [ 
    trigger( 
     'updatingTrigger', [ 
     transition('* => otherWriting', animate(1000, keyframes([ 
      style ({ 'border-color' : 'var(--change-detect-color)', offset: 0 }), 
      style ({ 'border-color' : 'var(--main-color)', offset: 1 }) 
     ]))) 
    ]) 
    ], 
    providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ReactiveInputComponent), multi: true } ] 
}) 
export class ReactiveInputComponent implements ControlValueAccessor { 

    public updatingState : string = null; 
    _value = ''; 

    // stores the action in the attribute (onModelChange) in the html template: 
    propagateChange:any = (change) => {}; 

    constructor(private ref: ChangeDetectorRef) { } 

    // change from the model 
    writeValue(value: any): void 
    { 
    this._value = value; 
    this.updatingState = 'otherWriting'; 

    window.setTimeout(() => { 
     this.updatingState = null; 
    }, 100); 

    // model value has change so changes must be detected (case ChangeDetectorStrategy is OnPush) 
    this.ref.detectChanges(); 
    } 

    // change from the UI 
    set value(event: any) 
    { 
    this._value = event; 
    this.propagateChange(event); 
    this.updatingState = null; 
    } 

    get value() 
    { 
    return this._value; 
    } 

    registerOnChange(fn: any): void { this.propagateChange = fn; } 
    registerOnTouched(fn:() => void): void {} 
    setDisabledState?(isDisabled: boolean): void {}; 
} 
1

Der einfachste und sauberer Weg, ich ist denken kann, wie so 2 CSS-Klassen zu implementieren:

.highlight{ 
    background-color: #FF0; 
} 
.kill-highlight{ 
    background-color: #AD310B; 
    -webkit-transition: background-color 1000ms linear; 
    -ms-transition: background-color 1000ms linear; 
    transition: background-color 1000ms linear; 
} 

und dann beide nacheinander auf das Element beeinflussen. hoffe das hilft

+0

Genauer gesagt war meine Frage, wie CSS-Klassen beeinflusst werden, wenn eine Änderung im Modell auftritt. Ich werde eine Lösung posten. – abreneliere

Verwandte Themen