为什么我的 属性 观察者被同一个 'newValue' 调用了两次?
Why is my property observer being called twice with the same 'newValue'?
我正在制作一个添加千位分隔符的观察器,可以是“.”。或 ',', 到用户键入的任何数字。
对于那些不知道的人,在 Polymer 中可以将观察者绑定到 属性,这基本上是每次 属性 更改时调用的函数。
使用两个参数调用观察者,'newValue' 和 'oldValue' 非常不言自明的参数名称。
现在它正确地添加了分隔符,但是当我按下删除键时它并没有删除它应该删除的内容。
这是我的用例:
1) 我输入“123456”。
2) 代码将其更改为“123.456”。
3) 我将光标放在最后一个位置 '123.456|' 上按删除键。
4) 观察者被调用了3次
第一个 'newValue' = '123.45'。 属性 和显示的数字更新为“12.345”。
由于 属性 已更改,因此第二次调用观察者 'newValue' = '12.345'。 属性 和显示的数字更新为相同的值(我不知道为什么,它本身没有改变....但让我们继续)。
这次观察者被称为 AGAIN ,这很奇怪,因为它与之前的值相同。 'newValue' 等于 '123.456'(我不明白), 属性 和显示的数字 returns 到初始状态(见步骤 2)。
我首先开始使用 属性 观察器,但当我想到这个问题时,我转而使用输入监听器,因为它可以让我检查 inputType 属性 并采取相应的行动。
删除操作时,输入类型为'contentDeleteBackward',插入操作时,输入类型为'insertText'。
这是观察者函数
_turnoverObserver: function (newValue, oldValue) {
let parsedWithoutCommas = String(parseInt(newValue.replace(/\D/g, ''), 10));
if (parsedWithoutCommas !== oldValue) {
this.fire('turnover-event', {turnover: parsedWithoutCommas});
let result = [];
let reversed = parsedWithoutCommas.split("").reverse();
if (reversed.length > 3) {
reversed.forEach((digit, index) => {
if (index !== 0 && index % 3 === 0) {
result.push('.');
}
result.push(digit);
});
this.turnover = result.reverse().join("");
}
}
},
这是输入监听函数
_addSeparatorTurnover (e) {
let value = e.target.value;
let parsedWithoutCommas = String(parseInt(value.replace(/\D/g, ''), 10));
if (e.inputType === 'insertText') {
let result = [];
if (parsedWithoutCommas.length > 3) {
let reversed = parsedWithoutCommas.split('').reverse();
reversed.forEach((num, index) => {
if (index !== 0 && index % 3 === 0) {
result.push('.');
}
result.push(num);
});
e.target.value = result.reverse().join('');
}
} else {
let result = [];
let {selectionStart, selectionEnd} = e.target.$.input;
let deletedVal = parsedWithoutCommas.slice(0, selectionStart - 2) + parsedWithoutCommas.slice(selectionStart - 1);
deletedVal.split('').reverse().forEach((num, index) => {
if (index !== 0 && index % 3 === 0) {
result.push('.');
}
result.push(num);
});
e.target.value = result.reverse().join('');
}
},
输入“123456”应显示“123.456”
删除“123.456”的最后一位应该将其更改为“12.345”
我尝试使用您的代码,发现 属性 上的观察者恰好调用了两次,而不是您提到的三次。但是,我已经从您的代码中注释了以下行。
`this.fire('turnover-event', {turnover: parsedWithoutCommas});`
即使在上述事件中,您也有可能试图更改相同的值,并可能导致第三次调用。
此外,您的代码在插入数字时似乎可以正常工作。如果我们开始删除数字,它将在 4 位以下按预期停止工作。 IE。,
对于 4 位数字,它显示 1.234,如果您再删除一位,它显示 1.23,这与您的预期(假设)不正确。
我调整了您的代码,下面的代码运行良好。
_turnoverObserver: function(newValue, oldValue) {
if (newValue) {
let parsedWithoutCommas = String(parseInt(newValue.replace(/\D/g, ''), 10));
if (parsedWithoutCommas !== oldValue) {
//this.fire('turnover-event', { turnover: parsedWithoutCommas });
let result = [];
let reversed = parsedWithoutCommas.split("").reverse();
if (reversed.length >= 3) {
reversed.forEach((digit, index) => {
if (index !== 0 && index % 3 === 0) {
result.push('.');
}
result.push(digit);
});
this.somevalue = result.reverse().join("");
}
}
}
}
我正在制作一个添加千位分隔符的观察器,可以是“.”。或 ',', 到用户键入的任何数字。
对于那些不知道的人,在 Polymer 中可以将观察者绑定到 属性,这基本上是每次 属性 更改时调用的函数。
使用两个参数调用观察者,'newValue' 和 'oldValue' 非常不言自明的参数名称。
现在它正确地添加了分隔符,但是当我按下删除键时它并没有删除它应该删除的内容。
这是我的用例:
1) 我输入“123456”。
2) 代码将其更改为“123.456”。
3) 我将光标放在最后一个位置 '123.456|' 上按删除键。
4) 观察者被调用了3次
第一个 'newValue' = '123.45'。 属性 和显示的数字更新为“12.345”。
由于 属性 已更改,因此第二次调用观察者 'newValue' = '12.345'。 属性 和显示的数字更新为相同的值(我不知道为什么,它本身没有改变....但让我们继续)。
这次观察者被称为 AGAIN ,这很奇怪,因为它与之前的值相同。 'newValue' 等于 '123.456'(我不明白), 属性 和显示的数字 returns 到初始状态(见步骤 2)。
我首先开始使用 属性 观察器,但当我想到这个问题时,我转而使用输入监听器,因为它可以让我检查 inputType 属性 并采取相应的行动。
删除操作时,输入类型为'contentDeleteBackward',插入操作时,输入类型为'insertText'。
这是观察者函数
_turnoverObserver: function (newValue, oldValue) {
let parsedWithoutCommas = String(parseInt(newValue.replace(/\D/g, ''), 10));
if (parsedWithoutCommas !== oldValue) {
this.fire('turnover-event', {turnover: parsedWithoutCommas});
let result = [];
let reversed = parsedWithoutCommas.split("").reverse();
if (reversed.length > 3) {
reversed.forEach((digit, index) => {
if (index !== 0 && index % 3 === 0) {
result.push('.');
}
result.push(digit);
});
this.turnover = result.reverse().join("");
}
}
},
这是输入监听函数
_addSeparatorTurnover (e) {
let value = e.target.value;
let parsedWithoutCommas = String(parseInt(value.replace(/\D/g, ''), 10));
if (e.inputType === 'insertText') {
let result = [];
if (parsedWithoutCommas.length > 3) {
let reversed = parsedWithoutCommas.split('').reverse();
reversed.forEach((num, index) => {
if (index !== 0 && index % 3 === 0) {
result.push('.');
}
result.push(num);
});
e.target.value = result.reverse().join('');
}
} else {
let result = [];
let {selectionStart, selectionEnd} = e.target.$.input;
let deletedVal = parsedWithoutCommas.slice(0, selectionStart - 2) + parsedWithoutCommas.slice(selectionStart - 1);
deletedVal.split('').reverse().forEach((num, index) => {
if (index !== 0 && index % 3 === 0) {
result.push('.');
}
result.push(num);
});
e.target.value = result.reverse().join('');
}
},
输入“123456”应显示“123.456”
删除“123.456”的最后一位应该将其更改为“12.345”
我尝试使用您的代码,发现 属性 上的观察者恰好调用了两次,而不是您提到的三次。但是,我已经从您的代码中注释了以下行。
`this.fire('turnover-event', {turnover: parsedWithoutCommas});`
即使在上述事件中,您也有可能试图更改相同的值,并可能导致第三次调用。 此外,您的代码在插入数字时似乎可以正常工作。如果我们开始删除数字,它将在 4 位以下按预期停止工作。 IE。, 对于 4 位数字,它显示 1.234,如果您再删除一位,它显示 1.23,这与您的预期(假设)不正确。 我调整了您的代码,下面的代码运行良好。
_turnoverObserver: function(newValue, oldValue) {
if (newValue) {
let parsedWithoutCommas = String(parseInt(newValue.replace(/\D/g, ''), 10));
if (parsedWithoutCommas !== oldValue) {
//this.fire('turnover-event', { turnover: parsedWithoutCommas });
let result = [];
let reversed = parsedWithoutCommas.split("").reverse();
if (reversed.length >= 3) {
reversed.forEach((digit, index) => {
if (index !== 0 && index % 3 === 0) {
result.push('.');
}
result.push(digit);
});
this.somevalue = result.reverse().join("");
}
}
}
}