2011-06-05 167 views
19

我有一个viewModel answerGroup对象的数组。当其中一个answerGroup对象的feedback属性更新时,我想通过将ajax传递给我的ASP.Net MVC应用程序来将更新的对象保存到我的数据库中。事件绑定在knockout.js

而不是有一个典型的保存按钮或链接,我希望对象的属性已更新时传递给Ajax调用。我想我可以通过绑定到textarea元素的change事件来做到这一点,但如果我这样做,ajax函数被调用,但底层answerGroup对象的反馈属性不会更新。

我正在使用淘汰赛1.2.1。下面是javascript代码,我没有包含HTML。

我是以这种错误的方式去做的,还是仅仅是我的knockout.js事件绑定语法不正确?

任何人都可以帮忙吗?

<script> 
var viewModel = {} 

$(function() { 
    viewModel.scenarioId = ko.observable($("#Scenario_ScenarioID").val()); 
    viewModel.answerGroups = ko.observableArray([]); 
    viewModel.addGroup = function (answerGroup) { 

     // add item to beginning of array 
     this.answerGroups.unshift(answerGroup); 
    }; 

    ko.applyBindings(viewModel); 
}); 

function answerGroup() { 
    this.id = ko.observable(); 
    this.name = ko.observable(); 
    this.feedback = ko.observable(); 

    // the groups feedback has been updated so save 
    // these details back to the server 
    this.updateGroup = function (event) { 

     // javascript api library that is an ajax function. 
     // this works without a problem. 
     api.updateAnswerGroup({ 
     success: function (result) { 
      alert("saved!"); 
     }, 
     error: function (e) { 
      alert("error!"); 
     }, 
     data: "answerGroupId=" + this.id + "&feedback=" + this.feedback 
     }); 

     return true; 
    }; 
} 
</script> 

<script id="answerGroupsTemplate" type="text/html"> 
    <div> 
    <h4><a href='#'>${ $data.name }</h4> 
    <div> 
     <textarea cols="100" rows="2" data-bind="event: { text: feedback, change: updateGroup }"> 
     </textarea>     
    </div> 
    </div> 
</script> 
+0

也许我懒,但我认为它太多的代码。哪一部分是相关部分 – Ibu 2011-06-05 18:47:44

+0

伊布 - 所有这些都是相关的,我没有列入不相关的部分。 – Robini 2011-06-05 20:38:40

+0

updateGroup函数被调用,但反馈属性的基础值未更新。我需要反馈属性来更新,然后调用updateGroup函数,以便我可以将此属性的值传递回服务器。 – Robini 2011-06-05 20:41:28

回答

42

在Knockout中处理此问题的典型方法是对您想要对变化作出反应的可观察项进行手动订阅。

所以,你会做这样的事情:

function answerGroup() { 
    this.id = ko.observable(); 
    this.name = ko.observable(); 
    this.feedback = ko.observable(); 

    this.feedback.subscribe(function (newValue) { 
     //run your update code here 
    }, this); 
} 

的第二个参数的订阅功能控制上下文(“本”),当函数运行。

关于这样的订阅的好处在于,当observable以编程方式更改或基于UI中的绑定进行更改时,它将触发。在这里

简要文档:http://knockoutjs.com/documentation/observables.html#explicitly-subscribing-to-observables

我有一个职位,其中包括使用手动订阅here太多信息。

希望这会有所帮助。

+0

我已阅读关于订阅,自定义绑定等的knockout.js网站上的文档,但您的文章将它放在我的上下文中。工作很好。现在,我添加了订阅的一段代码,并在函数中插入了一条警告,但它并未触发。有任何想法吗? – Robini 2011-06-05 21:19:23

+0

如果我向viewModel添加一个订阅,但它会触发,即viewModel.answerGroups.subscribe(function(newValue){alert(newValue);},this); – Robini 2011-06-05 21:44:27

+0

你的绑定看起来像反馈可观察的东西吗?你使用价值绑定? – 2011-06-05 22:13:08

4

我更喜欢订阅观察像RP尼迈耶如何描述,但有时你需要附加到一个事件,而不是观察。因此您可以使用“事件”绑定。文档不包括“改变”事件,但我已经与版本v2.0.0rc尝试过了,它的工作原理:

<input data-bind="value: viewModel.MyProperty, event: { change: viewModel.MyPropertyChanged } /> 

http://knockoutjs.com/documentation/event-binding.html