Я использую нокаут (KO) в своем проекте MVC. Я создаю модель MVC (для сетки) на сервере и передаю ее в представление. По представлению он сериализуется и преобразуется в модель KO (с использованием ko.mapping), которая, в свою очередь, используется для привязки. Это связывание затем используется в HTML для создания сетки.Нокаутное отображение наблюдаемого массива не работает
Это как моя модель сетки MVC выглядит в свою очередь, преобразуется в соответствующей модели KO по ko.mapping:
public class GridModel
{
/// <summary>
/// Grid body for the grid.
/// </summary>
public GridBodyModel GridBodyModel { get; set; }
/// <summary>
/// Grid context.
/// </summary>
public GridContext GridContext { get; set; }
/// <summary>
/// Grid header for the grid.
/// </summary>
public GridHeaderModel GridHeader { get; set; }
}
public class GridBodyModel
{
/// <summary>
/// List of grid body rows.
/// </summary>
public IList<GridRowModel> Rows { get; set; }
}
public class GridContext
{
/// <summary>
/// Total number of pages. Read-only.
/// </summary>
public int TotalPages{ get; set; }
}
public class GridHeaderModel
{
/// <summary>
/// List of grid header cells.
/// </summary>
public IList<GridHeaderCellModel> Cells { get; set; }
}
Как видно основной класс модели GridModel состоит из следующих классов, которые present as properties:
GridBodyModel: содержит список строк, которые будут отображаться в теле сетки.
GridContext: Общее количество страниц. Он имеет и другие свойства, но это выходит за рамки этого обсуждения.
GridHeaderModel: содержит список ячеек, которые должны отображаться в заголовке сетки.
Тогда у меня есть этот скрипт, который будет выполняться при новой загрузке страницы.
$(document).ready(function() {
// Apply Knockout view model bindings when document is in ready state.
ko.applyBindings(Global_GridKOModel, document.getElementById("gridMainContainer"));
});
// Serialize the server model object. It will be used to create observable model.
Global_GridKOModel = ko.mapping.fromJS (<%= DataFormatter.SerializeToJson(Model) %>);
Global_GridKOModel является глобальной переменной Javascript. Модель - модель сетки MVC, поступающая с сервера.
Пользователь может выполнить дальнейший поиск на странице еще раз. Я обрабатываю это путем публикации новых критериев поиска через Ajax. На этом посту создается новая модель MVC и отправляется обратно как ответ Ajax. Эта новая модель MVC затем просто используется для обновления Global_GridKOModel с использованием ko.mapping, которая, в свою очередь, обновляет сетку (с новыми данными), которая была построена ранее при новой загрузке страницы. Вот как я это делаю.
$.ajax({
url: destUrl,
data: dataToSend
success: function (result) {
ko.mapping.fromJS(result, Global_GridKOModel);
},
error: function (request, textStatus, errorThrown) {
alert(request.statusText);
}
});
Все работает нормально, за исключением следующего сценария.
Выполняется запрос Ajax, для которого результат не возвращается. I.e. GridBodyModel и GridHeaderModel имеет значение null в модели GridModel. Эта сетка времени правильно показывает, что запись не найдена. Это верно. Это происходит с помощью следующей привязки HTML.
<!-- When no record is found. -->
<div data-bind="ifnot: GridContext.GridPager.TotalPages() > 0">
No record(s) were found.
</div>
<!-- This is actual grid table container. This is binded when records are found -->
<div data-bind="if: GridContext.TotalPages() > 0">
Grid construction happens here
</div>
Теперь после того, как это, если другой запрос Ajax сделан, но на этот раз записи возвращаются (я проверил реакцию с поджигатель и он подтвердил, что записи действительно возвращается). Это временное построение сетки происходит, когда доступны различные наблюдаемые массивы. Например, для построения пейджера для следующей сетки является частью HTML-привязки, которую я написал.
<td data-bind="attr:{colspan: GridHeader.Cells().length }">
На этот раз KO выдает следующую ошибку, которая видна в firebug.
Невозможно проанализировать привязки. Сообщение: TypeError: GridHeader.Cells не является функцией; Наручников значение: атр: {Colspan:. GridHeader.Cells() длина}
Он отлично работает так долго есть записи возвращаются, но он ломает после записи не возвращается, как описана выше.Обратите внимание, что GridHeader был недействителен в более раннем ответе, когда никаких записей не было возвращено. Я чувствую запах чего-то подозрительного в ko.mapping. Я думаю, что есть проблема при отображении наблюдаемого массива.
Итак, что я не делаю правильно? Кто-нибудь, пожалуйста?
Пожалуйста, не стесняйтесь просить разъяснений, если я не упомянул ничего ясно.
Заранее благодарен.
Большое спасибо Артему за то, что вы нашли время для чтения. Да, вы правы, null не следует возвращать. Я тоже понял это вчера вечером, но не публиковал. Пожалуйста, прочтите мой ответ ниже, где я упомянул о своем наблюдении, и он отражает именно то, что вы сказали. – Aum