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 {};
}
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}' –
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
_In meinem Fall werden Änderungen nicht vom Benutzer durchgeführt._ - Können Sie ein Beispiel zeigen? –