Я застрял в проблеме привязки JS. У меня есть основная модель представления, привязанная к странице оболочки моего одностраничного приложения. Эта masterviewmodel контролирует, какой вид в данный момент виден (с помощью Sammy JS). Он также содержит ссылки на подмодели представлений, которые привязаны к представлениям.
var app = function () {
var self = this;
self.State = ko.observable('home');
self.Home = ko.observable(new homepageVm());
self.User = ko.observable(new userInfoVm());
self.Request = ko.observable(new requestVm());
};
Модель просмотра User имеет одно представление, к которому можно привязать следующее:
<div data-bind="with: User, visible: State() === 'user'">
.. snip ..
</div>
Привязка with: гарантирует, что к представлению привязана правильная подвидовая модель. Этот подход отлично работает как для домашнего просмотра, так и для просмотра информации пользователя.
RequestVm использует пользовательский интерфейс в стиле мастера и требует привязки к нескольким представлениям. Вот где я застрял.
<div data-bind="with: Request, visible: State() === 'request-step-1'">
.. snip ..
</div>
<div data-bind="with: Request, visible: State() === 'request-step-2'">
.. snip ..
</div>
<div data-bind="with: Request, visible: State() === 'request-step-3'">
.. snip ..
</div>
Привязки работают нормально, когда я запускаю сайт (Knockout не вызывает ошибок привязки). Но когда я начинаю передавать данные через виртуальные машины, они больше не обновляют пользовательский интерфейс, как будто все привязки нарушены (даже те, которые имеют одно представление, привязанное к ним, например пользовательская ВМ).
Если я включу только представление первого шага мастера, в результате чего у меня останется только одна привязка к виртуальной машине запроса вместо трех, все привязки в приложении снова начнут работать!
Я не понимаю, что вызывает это. Может ли нокаут привязать только одно наблюдаемое к одному элементу? Или я пробую что-то неподдерживаемое?
Обновление. Похоже, что-то происходит с observableArrays в моей виртуальной машине. Привязки к простым наблюдаемым работают нормально.
Вот одна из виртуальных машин:
function userInfoVm() {
var self = this;
self.UserName = ko.observable();
self.Beun = ko.observable();
self.LoadingUser = ko.observable(false);
self.LoadingObjects = ko.observable(false);
self.UserData = ko.observableArray([]);
self.UserObjects = ko.observableArray([]);
self.LoadUser = function (userName) {
self.LoadingUser(true);
$.get('UserData/UserDetail', { username: userName }, function (details) {
self.UserData(details);
self.Beun(JSON.stringify(details));
self.LoadingUser(false);
});
};
self.LoadObjects = function (userName) {
self.LoadingObjects(true);
$.get('UserData/UserObjects', { username: userName }, function (objects) {
alert(JSON.stringify(objects));
self.UserObjects([objects]);
self.LoadingObjects(false);
});
};
self.Load = function (userName) {
self.UserName(userName);
self.UserData(null);
self.UserObjects(null);
self.LoadUser(userName);
self.LoadObjects(userName);
};
};
И представление, которое потребляет данные из указанной виртуальной машины:
<div data-bind="with: User, visible: State() === 'user'">
<h1>
<button class="backbutton" onclick="history.back();">
</button>
Details for user <span data-bind="text: UserName"></span>
</h1>
<div class="display detail">
<table>
<tbody data-bind="foreach: UserData">
<tr>
<td class="property" data-bind="text: Key">
</td>
<td class="value" data-bind="text: Value">
</td>
</tr>
</tbody>
</table>
<div class="loader" data-bind="visible: LoadingUser">
Please wait while we process your request...
</div>
</div>
<div class="display detail">
<h1>
Objects and services for user <span data-bind="text: UserName"></span>
</h1>
<table class="detailtable">
<tbody data-bind="foreach: UserObjects">
<tr>
<td class="value">
<a class="service" data-bind="text: Value, attr: { href: '#/service/' + Key }" href="#">
</a>
</td>
</tr>
</tbody>
</table>
<div class="loader" data-bind="visible: LoadingObjects">
Please wait while we process your request...
</div>
</div>
Details for user <span data-bind="text: Beun"></span>
</div>
Массивы не уведомляют пользовательский интерфейс о данных, которые им передаются. Другие наблюдаемые объекты, включая объект .Beun, который содержит строковые данные из вызова AJAX, обновляются, как и ожидалось.