如何强制针对特定HTML元素进行淘汰更新?

时间:2014-08-27 22:13:38

标签: javascript html knockout.js

我理解它的方式,我有一个HTML元素绑定到koObservableArray中的特定属性。由于结构的设置,它没有绑定到自己的koObservable。

<input data-bind="value: A" id="x" />

提交表单时,会调用一个方法,将淘汰视图模型序列化为JSON。

这很好用,但现在我在表单上添加了一些输入清理。

function sanitize(){
  //compute sanitized value
  document.getElementById("x").value = sanitized_value;
}

现在,显然这也不会更新淘汰视图模型。我的问题是:给定一个特定的html元素(绑定到koObservableArray中的属性),如何强制koObservableArray中的属性也更新?

理想情况下,我需要能够在不更改任何淘汰代码的情况下执行此操作。我真正希望能够做的是在javascript中模拟导致淘汰视图模型更新的任何内容。我已经明白它会更新模糊,但是会调用:

document.getElementById("x").blur();

未导致视图模型更新。

4 个答案:

答案 0 :(得分:2)

不是聪明人,但你做错了:)如果你正在使用淘汰赛,你必须始终对视图模型进行操作。逻辑,清理等不应该直接触及DOM。考虑一下您希望将视图模型绑定到不同模板的情况。保持逻辑分离是淘汰的全部要点。

现在,这并没有解决你的问题,但如果我说服你,这将会:做你所说的,你需要一个可观察的可观察的阵列。因此,当您创建可观察数组时,将observable推入其中然后更改它们:

var viewModel = {
    mainArray: ko.observableArray()
};

// I understand you've got some probably complex mapping logic, let's say you get your array from the server, and then assign it like this:
viewModel.mainArray(arrayFromServer);

// In that case, do this:
ko.utils.arrayForEach(arrayFromServer, function(item) {
    item.A = ko.observable(item.A);
});
viewModel.mainArray(arrayFromServer);

// and now if you're worried about the trip back to the server:
var jsonStringForServer = viewModel.toJSON();
var plainJSObjectForServer = viewModel.toJS();

答案 1 :(得分:1)

我经常遇到这种情况,你需要改变事件!

以下是它的演示:http://jsfiddle.net/sifriday/q0yndje2/

演示代码:

<input id="x" data-bind="value: a"/>
// Create a view-model
vm = {
    A: ko.observable("a")
}

// Apply bindings; the input should now show 'a'
ko.applyBindings(vm);

// Change the value of the input outside of KO
document.getElementById("x").value = "b";

// Trigger change, to update the VM
var el = document.getElementById("x");
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", false, true);
el.dispatchEvent(evt);

// Echo the value of the vm.A to the console; it should be 'b'
console.log(vm.A());

或者如果你有jQuery,你可以使用

更轻松地完成这个活动
$("#x").trigger("change")

答案 2 :(得分:1)

获取所选元素的上下文。从上下文中,您可以访问基础视图模型,因此可以直接更改边界值。不要那样看待那个视图,这就是视图模型的用途。

<input id="x" data-bind="value: a"/>
var ele = document.getElementById('x');
var context = ko.contextFor(ele);
var vm = context.$root;
vm.a(value);

fiddle

答案 3 :(得分:1)

就个人而言,我不会依赖jQuery这样的事情,而不是你绝对必须这样做。你越是倾向于采用淘汰方式,你就越有可能将视图与模型紧密结合(从而降低可重用性)。这一点越明显,您的模型就越了解视图中的DOM元素。它在模型期望在视图中产生紧密耦合,实际上,它不应该以它需要知道的方式设计。

您可以轻松地将提交绑定放置到表单中,然后在模型内部清理数据,这样会更加清晰。这是一个例子:

<form data-bind="submit: ValidateSubmit">
    <input data-bind="value: someField" />
</form>

var myModel = {
   someField: ko.observable(),
   ValidateSubmit: function() {

      //sanitize fields within model here
      //...
      //...
      return true; //ensures submit occurs
   }
};