Javascript Knockout.js 中的事件绑定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6245014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
event binding in knockout.js
提问by Robini
I have a viewModel with an array of answerGroup objects. When the feedback property of one of the answerGroup objects is updated I want to save the updated object to my database by passing it via ajax to my ASP.Net MVC app.
我有一个带有 answerGroup 对象数组的 viewModel 。当 answerGroup 对象之一的反馈属性更新时,我想通过将更新的对象通过 ajax 传递到我的 ASP.Net MVC 应用程序来将更新的对象保存到我的数据库中。
Instead of having a typical save button or link, I want the object to be passed to the Ajax call when the object's property has been updated. I thought I could do this by binding to the change event of the textarea element but if I do this the ajax function is called but the underlying answerGroup object's feedback property is not updated.
我希望在更新对象的属性时将对象传递给 Ajax 调用,而不是使用典型的保存按钮或链接。我以为我可以通过绑定到 textarea 元素的更改事件来做到这一点,但如果我这样做,ajax 函数将被调用,但底层 answerGroup 对象的反馈属性不会更新。
I'm using Knockout 1.2.1. Below is the JavaScript code, I haven't included the HTML.
我正在使用淘汰赛 1.2.1。下面是 JavaScript 代码,我没有包含 HTML。
Am I going about this the wrong way or is it just that my syntax for the knockout.js event binding is incorrect?
我是在用错误的方式解决这个问题,还是只是我的 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>
回答by RP Niemeyer
The typical way to handle this in Knockout is to do a manual subscription on the observable that you want to react to changes on.
在 Knockout 中处理此问题的典型方法是手动订阅要对更改做出反应的 observable。
So, you would do something like:
所以,你会做这样的事情:
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);
}
The second parameter to the subscribe function controls the context ("this") when the function runs.
subscribe 函数的第二个参数控制函数运行时的上下文(“this”)。
The nice part about a subscription like this is that it will fire when the observable is changed programmatically or changed based on a binding in your UI.
像这样的订阅的好处在于,当以编程方式更改 observable 或基于 UI 中的绑定更改时,它将触发。
Brief docs on it here: http://knockoutjs.com/documentation/observables.html#explicitly-subscribing-to-observables
简要文档在这里:http: //knockoutjs.com/documentation/observables.html#explicitly-subscribing-to-observables
I had a post that included info on using manual subscriptions heretoo.
我有一篇文章,其中也包含有关在此处使用手动订阅的信息。
Hope this helps.
希望这可以帮助。
回答by Garry English
I prefer to subscribe to the observable like how RP Niemeyer describes, but sometime you need to attach to an event and not the observable. Therefore you can use the "event" binding. The documentation doesn't include the "change" event, but I have tried it with version v2.0.0rc and it works:
我更喜欢像 RP Niemeyer 描述的那样订阅 observable,但有时你需要附加到一个事件而不是 observable。因此,您可以使用“事件”绑定。该文档不包括“更改”事件,但我已经尝试过 v2.0.0rc 版本并且它有效:
<input data-bind="value: viewModel.MyProperty, event: { change: viewModel.MyPropertyChanged } />