【问题标题】:event binding in knockout.jsknockout.js 中的事件绑定
【发布时间】:2011-09-08 20:32:59
【问题描述】:

我有一个带有 answerGroup 对象数组的 viewModel。当 answerGroup 对象之一的反馈属性更新时,我想通过 ajax 将更新后的对象保存到我的数据库中。

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

我正在使用 Knockout 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>

【问题讨论】:

  • 也许我很懒,但我认为它的代码太多了。哪个部分是相关部分
  • Ibu - 所有这些都是相关的,我没有包括不相关的部分。
  • 调用了 updateGroup 函数,但未更新反馈属性的基础值。我需要更新反馈属性,然后调用 updateGroup 函数,以便我可以将此属性的值传回服务器。

标签: javascript jquery asp.net asp.net-mvc knockout.js


【解决方案1】:

在 Knockout 中处理此问题的典型方法是手动订阅您想要对更改做出反应的 observable。

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

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);
}

订阅函数的第二个参数控制函数运行时的上下文(“this”)。

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

这里有简短的文档:http://knockoutjs.com/documentation/observables.html#explicitly-subscribing-to-observables

我也有一篇帖子,其中包含有关使用手动订阅 here 的信息。

希望这会有所帮助。

【讨论】:

  • 我已经阅读了 knockout.js 网站上有关订阅、自定义绑定等的文档,但您的帖子为我提供了所有内容。不错的作品。现在,我添加了订阅代码并在函数中插入了一个警报,但它没有触发。有什么想法吗?
  • 如果我向 viewModel 添加订阅,但它确实会触发,即 viewModel.answerGroups.subscribe(function (newValue) { alert(newValue); }, this);
  • 您的绑定与可观察的反馈相比是什么样的?你在使用值绑定吗?
  • 我改了,是的,只使用值绑定 -
  • 你好——当你设置一个 observable 时,你需要像这样设置它:myObservable(myValue) 而不是myObservable = myValue。否则,您将变量重置为 myValue,而不是将 observable 设置为该值。 jsfiddle.net/rniemeyer/Sm65u/6
【解决方案2】:

我更喜欢像 RP Niemeyer 描述的那样订阅 observable,但有时您需要附加到事件而不是 observable。因此,您可以使用“事件”绑定。该文档不包括“更改”事件,但我已经尝试使用 v2.0.0rc 版本并且它可以工作:

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

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

【讨论】:

    猜你喜欢
    • 2015-02-10
    • 2012-09-16
    • 1970-01-01
    • 2013-05-02
    • 2012-12-13
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    相关资源
    最近更新 更多