Подтвердить что ты не робот

Привязка события в knockout.js

У меня есть viewModel с массивом объектов answerGroup. Когда свойство обратной связи одного из объектов answerGroup обновляется, я хочу сохранить обновленный объект в свою базу данных, передав его через ajax в мое приложение ASP.Net MVC.

Вместо того, чтобы иметь типичную кнопку или ссылку сохранения, я хочу, чтобы объект передавался на вызов Ajax, когда свойство объекта было обновлено. Я думал, что могу сделать это, привязавшись к событию изменения элемента textarea, но если я это сделаю, вызывается функция ajax, но базовое свойство обратной связи объекта ответаGroup не обновляется.

Я использую нокаут 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>
4b9b3361

Ответ 1

Типичный способ справиться с этим в 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);
}

Второй параметр функции подписки управляет контекстом ("this") при выполнении функции.

Хорошая часть подписки, подобная этой, заключается в том, что она срабатывает, когда наблюдаемое изменяется программно или изменено на основе привязки в вашем пользовательском интерфейсе.

Краткие документы на нем: http://knockoutjs.com/documentation/observables.html#explicitly-subscribing-to-observables

У меня была почта, в которой также была включена информация об использовании ручных подписчиков здесь.

Надеюсь, что это поможет.

Ответ 2

Я предпочитаю подписываться на наблюдаемое, как описано в RP Niemeyer, но когда-то вам нужно присоединяться к событию, а не наблюдаемому. Поэтому вы можете использовать привязку "событие". Документация не включает событие "change", но я пробовал ее с версией v2.0.0rc, и она работает:

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

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