#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 } />