绑定到ngModel的管道(纯或不纯)中的力变化检测

时间:2019-05-03 16:15:13

标签: angular angular6 angular-pipe angular2-changedetection angular-changedetection

我将ngModel值绑定到角度百分比管道,在ngModelChange上更新,并将updateOn设置为blur。除了再次输入相同的值时,它工作良好。再次输入相同的值时,管道不会检测到更改,并且该值显示为小数而不是百分比。我尝试将百分比管道重新创建为不纯管道,但这没有用。即使值与先前的值相同,如何强制管道检测变化?

试图让管道返回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-https://stackblitz.com/edit/angular-6-material-starter-ru3ks1

3 个答案:

答案 0 :(得分:3)

在尝试找到合适的解决方案时,我设法迫使纯currency管道以相同的值(here is the demo)重新执行。但这并不能解决问题,因为即使管道重新执行,它最终也会返回相同的结果。因为该结果像ngModel一样@Input绑定到[ngModel]="account.percentage | percent: '1.0-2'",就像ngModel implementation中的ngOnChanges ngModel钩子一样,不会更新输入元素的视图值。

(摘自sources,这是@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); } 的{​​{3}}

model

由于changes: SimpleChangesisPropertyUpdated中没有变化,<input *ngIf="dummy" placeholder="Percentage" type="text" [ngModel]="account.percentage | percent: '1.2-2'" (ngModelChange)="updateAssignments($event)" [ngModelOptions]="{updateOn:'blur'}" class="ta-r" /> 返回false,并且视图未更新。

所以我尝试了以下变通办法,从头开始重新初始化输入,并且它起作用了:)

我在输入上放置了一个虚拟变量以显示/隐藏元素;

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); } 发出输入信号时,该信号就会被隐藏并立即显示

ERROR: resizing partition e2fsck failed with exit code 8

== >>> implementation <<< ==

答案 1 :(得分:0)

由于将ngModelOptions设置为仅在模糊时更新,因此它将仅在模糊输入后才更新:)

删除它可以解决问题。

答案 2 :(得分:0)

尝试[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" />