angular - 绑定到 ngModel 的管道(纯或不纯)中的力变化检测
问题描述
我将 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);
}
期望值以百分比格式显示。重新输入后显示十进制值。
解决方案
在尝试找到合适的解决方案时,我设法强制纯currency
管道以相同的值重新执行(这里是演示)。但这并没有解决问题,因为即使管道重新执行,它最终也会返回相同的结果。因为该结果被绑定到ngModel 实现ngModel
中的@Input
钩子[ngModel]="account.percentage | percent: '1.0-2'"
ngOnChanges
,不会更新输入元素视图值。
这是(取自来源)如何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);
}
因为 inside 没有变化model
返回changes: SimpleChanges
isPropertyUpdated
false 并且视图没有更新。
所以我尝试按照hacky解决方法从头开始重新初始化输入并且它有效:)
我在输入上放置了一个虚拟变量来显示/隐藏元素;
<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);
}
==>>>这是一个工作演示<<<==
推荐阅读
- jasper-reports - jasper 报告 PDF 中错误显示的马拉雅拉姆语字体(以 HTML 格式工作)
- python - 从其他数据框排列创建数据框
- css - 带有固定标题的div中的滚动条问题
- android - 全局变量范围返回 [Object object] 而不是 node.js 中的字符串
- java - 我们可以在没有extends关键字的情况下访问B类中A类的变量和方法吗
- angular2-services - Angular 2 应用程序中的 HTTP 响应处理
- python - 如何缓存为 Alpine Linux 构建的 python 包 Docker?
- html - z-index 在材质侧导航上无法正常工作
- mysql - SQLite - 对来自三个不同表的列进行算术运算(求和、乘、减等)
- javascript - 单击弹出窗口中的链接