敲除对象的双向绑定

时间:2015-08-10 12:36:06

标签: javascript jquery html dom knockout.js

我正在尝试使用Knockout.js在javascript对象和一些DOM元素之间创建双向绑定。我希望我的对象能够反映DOM元素的变化,反之亦然。我成功实现了第一个目标,反之亦然,我无法开始工作。

JSFiddle demo

myPerson = {
    firstName : "",
    lastName : "",
    age  : null,
    test : function() {alert('Testing');}
};

myViewModel = function myViewModel(obj) {
    this.firstName = ko.observable();
    this.lastName = ko.observable();
    this.age = ko.observable();
    this.fullName = ko.computed(function() {
        obj.firstName = (this.firstName() || '');
        obj.lastName = (this.lastName() || '');
        obj.age = (this.age() || '');

        return (this.firstName() || '') + ' ' + (this.lastName() || '');
    }, this);
};

ko.applyBindings(new myViewModel(myPerson));



    //How to get property changes reflected in the DOM inputs?

当我在DOM输入中进行更改时,myPerson对象的属性会相应地更改。下一步是手动更改这些属性,并自动查看de DOM输入中反映的这些更改。我试图搞乱地图插件但到目前为止还没有雪茄。

1 个答案:

答案 0 :(得分:2)

仅使用KO,只更改myPerson对象的属性不会更改您的viewmodel,因此不会更新DOM。

“KO方式”是将视图模型与myPerson分开,并通过将observables作为函数调用来更新该视图模型,例如:

myViewModel.firstName("TheNewFirstName");

现代浏览器上,您可以使用访问者函数在myPerson上定义您的属性,然后可以引发视图模型会观看的事件或类似事件for,但这需要ECMAScript5(~2009)中添加的功能,这些功能存在于现代浏览器中,但不是IE8及更早版本。它也意味着有效地拥有双视图模型(myPersonmyViewModel)。

因此,在使用KO时,您通常只拥有viewmodel本身,并调用observable来更新它们。

这是一个简单的例子“KO方式”:

var vm = {
  counter: ko.observable(0)
};
ko.applyBindings(vm, document.querySelector('div'));
var timer = setInterval(function() {
  if (vm.counter() >= 20) {
    clearInterval(timer);
  } else {
    vm.counter(vm.counter() + 1);
  }
}, 1000);
<div>
  <span data-bind="text: counter"></span>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>

如果你只是想支持现代浏览器,并希望像你的myPerson那样使用类似KO的普通对象,你可能会看RivetsJS,它会将getter / setter应用于你的对象对你而言。

这是与铆钉相同的简单示例 - 但它不适用于ECMAScript5之前的引擎:

var obj = {
  counter: 0
};
rivets.bind(document.querySelector('div'), obj);
var timer = setInterval(function() {
  if (obj.counter >= 20) {
    clearInterval(timer);
  } else {
    ++obj.counter;
  }
}, 1000);
<div>
  {counter}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rivets/0.8.1/rivets.bundled.min.js"></script>

(这不是推荐,只是注意到了选项。我很高兴在正确的项目中使用KO;从未有机会对Rivets做同样的事情。)