valueAccessor() 在自定义绑定创建期间返回函数签名而不是值

valueAccessor() returning function signature instead of value during custom binding creation

我是 Knockout.js 的新手,一直在学习教程。但是,我的代码没有按预期工作,因为在我的自定义绑定中 createDecimalvalueAccessor() 返回函数的签名而不是实际值。

我使用的是截至今天的最新版本 Knockout.js,v3.4.2。

<p>First Name <strong data-bind="text: firstName"></strong></p>
<p>Last Name <strong data-bind="text: lastName"></strong></p>
<p>Change First Name <input data-bind="value: firstName, valueUpdate: 'afterkeydown'" type="text" name="firstName"></p>
<p>Change Last Name <input data-bind="value: lastName, valueUpdate: 'afterkeydown'" , type="text" name="lastName"></p>
<p>Full Name: <strong data-bind="text: fullName"></strong></p>
<p>Add new hobby: <input data-bind="value: hobby, valueUpdate: 'afterkeydown'" type="text" name="hobby"><button data-bind="click: addHobby">Add</button></p>
<p>Hobby to possibly be added: <strong data-bind="text: hobby"></strong></p>
<ul data-bind="foreach: hobbies">
  <div>
    <li data-bind="text: $data"></li>
    <button data-bind="click: $parent.removeHobby">Remove Hobby</button>
  </div>
</ul>
<p>Total Number of Properties: <strong data-bind="makeDecimal: numberOfHobbies"></strong></p>

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script type="text/javascript">
  ko.bindingHandlers.makeDecimal = {
    update: function(element, valueAccessor) {
      var numberOfHobbies = valueAccessor();
      console.log("Number of Hobbies", numberOfHobbies);
      var formattedText = "$" + numberOfHobbies.toFixed();
      element.innerText = formattedText;
    }
  };

  function IndexViewModel() {
    var self = this;
    self.firstName = ko.observable("George");
    self.lastName = ko.observable("Lopez");
    self.hobby = ko.observable();
    self.hobbies = ko.observableArray(["Acting", "Joking", "Speaking"]);
    self.addHobby = function() {
      self.hobbies.push(self.hobby());
    };
    self.removeHobby = function(hobby) {
      self.hobbies.remove(hobby);
    };

    self.fullName = ko.computed(function() {
      return self.firstName() + " " + self.lastName();
    });

    self.numberOfHobbies = ko.computed(function() {
      return self.hobbies().length;
    });

  }

  ko.applyBindings(new IndexViewModel());
</script>

这不是很自然,但是这里你需要使用ko.unwrap()来获取observable的值。

ko.bindingHandlers.makeDecimal = {
    update: function(element, valueAccessor) {
        var numberOfHobbies = ko.unwrap(valueAccessor());
        console.log("Number of Hobbies", numberOfHobbies);
        var formattedText = "$" + numberOfHobbies.toFixed();
        element.innerText = formattedText;
    }
};

这是因为 Knockout 管理可观察对象的方式,用函数替换它们。