为什么使用相同的“ newValue”调用我的属性观察器两次?

时间:2019-04-08 16:19:03

标签: javascript polymer

我正在使观察者添加一个千位分隔符,它是一个'。'。或',',无论用户键入什么数字。

对于那些不知道的人,在Polymer中可以将观察者绑定到属性,该属性基本上是每次属性更改时都会调用的函数。

使用两个参数调用观察者,它们分别是'newValue'和'oldValue'漂亮的不言自明的参数名称。

现在,它可以正确添加分隔符,但是当我按Delete时,它并不会删除应该删除的内容。

这是我的用例:

1)我键入“ 123456”。

2)代码将其更改为“ 123.456”。

3)我用光标在最后一个位置'123.456 |'按Delete键。

4)观察者被叫了三遍。

  • 第一个具有'newValue'='123.45'的对象。该属性和显示的数字已更新为“ 12.345”。

  • 随着属性的更改,使用'newValue'= '12 .345'再次调用了观察者。该属性和显示的数字将更新为相同的值(我不知道为什么,它本身并没有更改。...但是让我们继续)。

  • 这一次将观察者称为AGAIN,这很奇怪,因为它的值与以前相同。 “ newValue”等于“ 123.456”(我不了解),显示的属性和数字返回到初始状态(请参阅步骤2)。

我首先开始使用属性观察器,但是当我想到此问题时,我切换到使用输入侦听器,因为它可以检查inputType属性并采取相应的措施。

删除操作时,inputType为'contentDeleteBackward',插入时,inputType为'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”

1 个答案:

答案 0 :(得分:0)

我尝试使用您的代码,并且可以看到该属性的观察者恰好调用了两次,而不是您提到的三次。但是,我已经从您的代码中注释了以下行。

`this.fire('turnover-event', {turnover: parsedWithoutCommas});`

即使在上述事件中,也有可能您试图更改相同的值,并可能导致第三个调用。 另外,插入数字时,您的代码似乎可以正常工作。如果我们开始删除数字,它将停止正常工作,低于4位数字。即 对于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("");
                        }
                    }
                }
            }