пытаясь найти правильное решение, мне удалось заставить чистый канал currency
повторно выполнить с тем же значением (вот демонстрация). но это не решило проблему, потому что даже если конвейер повторно запускается, он в конечном итоге возвращает тот же результат. так как этот результат привязан к ngModel
как @Input
как [ngModel]="account.percentage | percent: '1.0-2'"
ngOnChanges
в хуке реализация ngModel не обновляет значение представления элементов ввода.
это (взято из источников a>) как ngModel
фиксирует изменения и обновляет значение / представление.
@Input('ngModel') model: any;
...
ngOnChanges(changes: SimpleChanges) {
this._checkForErrors();
if (!this._registered) this._setUpControl();
if ('isDisabled' in changes) {
this._updateDisabled(changes);
}
if (isPropertyUpdated(changes, this.viewModel)) {
this._updateValue(this.model);
this.viewModel = this.model;
}
}
и это реализация > из isPropertyUpdated
export function isPropertyUpdated(changes: { [key: string]: any }, viewModel: any): boolean {
if (!changes.hasOwnProperty('model')) return false;
const change = changes['model'];
if (change.isFirstChange()) return true;
return !looseIdentical(viewModel, change.currentValue);
}
// https://github.com/angular/angular/blob/53212db3ed48fe98c0c0416ae0acee1a7858826e/packages/core/src/util/comparison.ts#L13
export function looseIdentical(a: any, b: any): boolean {
return a === b || typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b);
}
поскольку нет изменений в model
в пределах changes: SimpleChanges
isPropertyUpdated
возвращает false и представление не обновляется.
поэтому я попытался выполнить обходной путь, чтобы повторно инициализировать ввод с нуля, и это сработало :)
я поместил фиктивную переменную на ввод, чтобы показать / скрыть элемент;
<input
*ngIf="dummy"
placeholder="Percentage"
type="text"
[ngModel]="account.percentage | percent: '1.2-2'"
(ngModelChange)="updateAssignments($event)"
[ngModelOptions]="{updateOn:'blur'}"
class="ta-r"
/>
и всякий раз, когда ngModelChange
излучает, ввод скрывается и сразу отображается
dummy = true;
constructor(private cdRef: ChangeDetectorRef){}
updateAssignments($event) {
const cleanEvent = Number($event.replace(/[^\d.]/g, ''));
this.account.percentage = (cleanEvent / 100);
this.dummy = false;
this.cdRef.detectChanges();
this.dummy = true;
this.cdRef.detectChanges();
console.log("account.percentage:", this.account.percentage);
}
== >>> вот рабочая демонстрация ‹*** = знак равно
person
ysf
schedule
10.07.2019