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

#javascript #jquery #asp.net #asp.net-mvc #knockout.js

#javascript #jquery #asp.net #asp.net-mvc #knockout.js

Вопрос:

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

Вместо обычной кнопки сохранения или ссылки я хочу, чтобы объект передавался вызову Ajax при обновлении свойства объекта. Я думал, что смогу сделать это путем привязки к событию изменения элемента textarea, но если я сделаю это, вызывается функция 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   "amp;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>
  

Комментарии:

1. может быть, я ленив, но я думаю, что это слишком много кода. какая часть является релевантной

2. Ibu — все это имеет отношение к делу, я не включил части, не подлежащие возврату.

3. Вызывается функция updateGroup, но базовое значение свойства обратной связи не обновляется. Мне нужно обновить свойство feedback, а затем вызвать функцию updateGroup, чтобы я мог передать значение этого свойства обратно на сервер.

Ответ №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);
}
  

Второй параметр функции subscribe управляет контекстом («this») при запуске функции.

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

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

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

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

Комментарии:

1. Я прочитал документы по knockout.js веб-сайт, касающийся подписок, пользовательских привязок и т.д., Но ваш пост поместил все это в контекст для меня. Отличная работа. Теперь я добавил фрагмент кода subscribe и вставил предупреждение внутри функции, но оно не запускается. Есть идеи?

2. Однако, если я добавлю подписку к ViewModel, она сработает, т.Е. ViewModel.answerGroups.subscribe(функция (новое значение) { оповещение (новое значение); }, это);

3. Как выглядит ваша привязка на фоне наблюдаемой обратной связи? Используете ли вы привязку значения?

4. Я изменил это да, чтобы использовать только привязку значения — <textarea cols=»100″ rows =»2″ data-bind=»значение: обратная связь»></textarea>

5. Здравствуйте — Когда вы устанавливаете наблюдаемое, вам нужно будет установить его следующим образом: myObservable(myValue) вместо myObservable = myValue . В противном случае вы сбрасываете переменную на myValue , а не устанавливаете для наблюдаемого это значение. jsfiddle.net/rniemeyer/Sm65u/6

Ответ №2:

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

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

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