Загрузка нокаута .js observableArray() из вызова .ajax()
Это меня озадачивает. это должно быть что-то маленькое, я не вижу. Я пытаюсь загрузить очень простой observableArray
в нокаут с помощью вызова ajax.
Javascript
// we bind the array to the view model property with an empty array.
var data = [];
var viewModel = {
vendors: ko.observableArray(data)
};
ko.applyBindings(viewModel);
$(function () {
// on this click event, we popular the observable array
$('#load').click(function () {
// WORKS. Html is updated appropriately.
viewModel.vendors([{ "Id": "01" },{ "Id": "02" },{ "Id": "03" }]);
// DOES NOT WORK. Fiddler2 shows the same exact json string come back
// as in the example above, and the success function is being called.
$.ajax({
url: '/vendors/10',
dataType: 'json',
success: function (data) {
viewModel.vendors(data);
}
});
});
});
HTML
<button id="load">Load</button>
<ul data-bind="template: { foreach: vendors }">
<li><span data-bind="text: Id"></span></li>
</ul>
Вопрос: Почему успешный вызов ajax, значение переменной data
соответствует байту за байтом жесткого типизированного значения, не вызывает обновление html?
Ответы
Ответ 1
Нет причин, чтобы это не сработало. Как это видно.
http://jsfiddle.net/madcapnmckay/EYueU/
Я бы проверял, что пост ajax фактически возвращает json-данные и что json является массивом и что он правильно разбирается.
Мне пришлось подстроить вызов ajax, чтобы заставить обработчики ajax скрипки работать правильно.
Больше ничего не могу придумать.
Надеюсь, что это поможет.
Ответ 2
var self=this;
//var self first line in model
$.ajax({
url: ",
dataType: "json",
contentType: 'application/json',
type: "POST",
data: JSON.stringify({ }),
processdata: true,
beforeSend: function () {
$.mobile.loading('show');
},
error: function (xhr, textStatus, errorThrown) {
alert('Sorry!');
},
success: function (data) {
$.mobile.loading('hide');
if (data.result!= '') {
self.vendors(data.result);
} else {
self.vendors({something});
}
}
});
Использовать self.vendors не этот viewModel.vendors
Ответ 3
Вот что я сделал в своем приложении MVC.net с нокаутом и jquery.
// Scripts/groItems.js
(function () {
var ViewModel = function () {
items = ko.observableArray(),
ItemName = ko.observable(),
Img = ko.observable(),
Qty = ko.observable()
}
$.getJSON('/Items2/AllItems', function (data) {
for (var i = 0; i < data.length; i++) {
self.items.push(data[i]);
}
});
var vm = new ViewModel();
$(function () {
ko.applyBindings(vm);
});
}());
@model IEnumerable<GroModel.Item>
@{
ViewBag.Title = "Index";
}
<p>
@Html.ActionLink("Create New", "Create")
</p>
<div data-bind="text: items().length"></div>
<table class="container table table-hover">
<thead>
<tr>
<th>Item name</th>
<th>img</th>
<th>qty</th>
</tr>
</thead>
<tbody data-bind="foreach: items">
<tr>
<td data-bind="text: ItemName"></td>
<td data-bind="text: Img"></td>
<td data-bind="text: Qty"></td>
</tr>
</tbody>
</table>
@section Scripts {
<script src="~/Scripts/knockout-3.4.2.js"></script>
<script src="~/Scripts/groItems.js"></script>
}
Ответ 4
Я слишком поздно отношусь к этому, так как я оказался в этой ситуации совсем недавно.
Мы можем использовать простую функцию использования JavaScript в качестве рабочего процесса.
Вместо viewModel.vendors(data);
мы можем использовать
eval("viewModel.vendors("+JSON.stringify(data)+");");...
Это сработало для меня.
Ответ 5
Это ошибка, я думаю, пример нокаута работает, когда мы используем его с классом-оболочкой:
public class ResultWrapper
{
public Title {get;set;}
public List<Result> {get;set;}
}
http://learn.knockoutjs.com/#/?tutorial=webmail
Но если мы вернем результаты напрямую, нет способа связать его. (без дополнительных applyBindings!)