Обнаружение изменения силы в трубе (чистой или нечистой), связанной с ngModel - PullRequest
4 голосов
/ 03 мая 2019

Я привязываю значение ngModel к угловой трубе процента, обновляя ngModelChange с updateOn, установленным на размытие.Он работает хорошо, за исключением повторного ввода того же значения.При повторном вводе того же значения канал не обнаруживает изменения, и значение отображается в виде десятичного числа вместо процента.Я пытался воссоздать процентную трубу как нечистую, но это не сработало.Как я могу заставить трубу обнаруживать изменение, даже если значение идентично предыдущему значению?

Попытка возврата трубы WrappedValue.wrap(this._latestValue);

Пробная работа this._ref.detectChanges() в функции изменения

<input placeholder="Percentage" type="text" 
       [ngModel]="account.percentage | percent: '1.0-2'"
       (ngModelChange)="updateAssignments($event)" 
       [ngModelOptions]="{updateOn:'blur'}" class="ta-r" />
updateAssignments($event) {
    const cleanEvent = Number($event.replace(/[^\d.]/g, ''));
    account.percentage = (cleanEvent / 100);
}

Ожидаемое значение будет отображаться в формате процента.Показывает десятичное значение после повторного входа.

Мой код Stackblitz

Ответы [ 3 ]

3 голосов
/ 11 июля 2019

, пытаясь найти правильное решение, мне удалось заставить чистый currency канал повторно выполнить с тем же значением ( - это демо ).но это не решило проблему, потому что, даже если канал повторно выполняется, он в конечном итоге возвращает тот же результат.поскольку этот результат привязан к ngModel как @Input, как [ngModel]="account.percentage | percent: '1.0-2'" ngOnChanges, подключается к реализации ngModel не обновляет значение представления входных элементов.

это (взято из sources ) как 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);
}

== >>> вот рабочая демоверсия <<< == </p>

0 голосов
/ 10 июля 2019

Попробуйте [ngModelOptions]="{updateOn:'change'}"

https://stackblitz.com/edit/angular-6-material-starter-rdxhte?file=src/app/hello.component.html

<input placeholder="Percentage" type="text" 
       [ngModel]="account.percentage | percent: '1.0-2'"
       (ngModelChange)="updateAssignments($event)" 
       [ngModelOptions]="{updateOn:'change'}" class="ta-r" />
0 голосов
/ 03 мая 2019

Он будет обновляться только после размытия ввода, поскольку вы устанавливаете ngModelOptions для обновления только при размытии:)

Удаление этого должно помочь.

...