Oto moje rozwiązanie.
Chciałem podkreślić dane w formularzu, które zostały zmienione przez innych użytkowników w czasie rzeczywistym.
W mojej formie HTML zastąpiłem natywne elementy HTML przez komponenty Angular. Dla każdego typu natywnego elementu stworzyłem nowy komponent kątowy z obsługą podświetlenia. Każdy komponent implementuje interfejs kątowy ControlValueAccessor.
W postaci dominującej Wymieniłem rodzimy element:
<input [(ngModel)]="itinerary.DetailWeather" />
przez mojego niestandardowego elementu:
<reactive-input [(ngModel)]="itinerary.DetailWeather"></reactive-input>
Kiedy kątowe połączeń detectChanges() w postaci dominującej, to jednak sprawdzić wszystkie dane, które są używane jako dane wejściowe przez składniki formularza.
Jeśli komponent jest AccessValueAccessor i zmiana wystąpiła w modelu aplikacji, wywołuje metodę ControlValueAccessor. writeValue (wartość). Jest to metoda, która jest wywoływana, gdy dane zmieniły się w pamięci. Używam go jako haka, aby tymczasowo zaktualizować styl, aby dodać atrakcję.
Oto niestandardowy element. Użyłem Angular Animations do aktualizacji koloru obramowania i przejścia do pierwotnego koloru.
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 {};
}
Czy to pytanie dotyczy tylko elementów wejściowych? i co masz na myśli przez "zmieniony"? - Słyszałem o specjalnych stylach klasowych Angular2_ - masz na myśli klasę "ng-dirty"? jeśli tak, spróbuj po prostu dodać styl dla 'input.ng-dirty {background-color: green}' –
Jest to specyficzne dla elementów z dyrektywą ngModel. Wydaje się, że ng-dirty/ng-touched nie zapewnia rozwiązania, ponieważ zależą one od działania użytkownika w sterowaniu. W moim przypadku zmiany nie są wykonywane przez użytkownika. To po prostu zmiana w modelu danych. – abreneliere
_W moim przypadku zmiany nie są wykonywane przez użytkownika._ - czy możesz pokazać przykład? –