Knockoutjs - ko.mapping.fromJS не работает
Я только что начал попробовать knockout.js. Ko.mapping предлагает отличный способ получить и отобразить данные с сервера. Однако я не могу заставить отображение работать.
У меня есть простая модель:
//var helloWorldModel;
var helloWorldModel = {
name: ko.observable('Default Name'),
message: ko.observable('Hello World Default')
};
$(document).ready(function() {
ko.applyBindings(helloWorldModel);
//a button on the form when clicked calls a server class
//to get json output
$('#CallServerButton').click(getDataFromServer);
});
function getDataFromServer() {
$.getJSON("HelloSpring/SayJsonHello/chicken.json", function(data) {
mapServerData(data);
});
}
function mapServerData(serverData) {
helloWorldModel = ko.mapping.fromJS(serverData, helloWorldModel);
alert(JSON.stringify(serverData));
}
У helloWorldModel есть только 2 атрибута - то же самое, что я возвращаюсь с сервера. Предупреждение в mapServerData показывает -
{"name":"chicken","message":"JSON hello world"}
Я просмотрел другие сообщения, касающиеся аналогичной проблемы, но никто из них, похоже, не решил эту проблему. Может быть, мне не хватает чего-то очень элементарного - интересно, может ли кто-нибудь указать это.
Также обратите внимание, если я не объявляю модель upfront и использую
helloWorldModel = ko.mapping.fromJS(serverData);
он правильно отображает данные в мою форму.
Ответы
Ответ 1
От Ричарда ответ, а затем немного больше исследований в этом, я думаю, что способ, которым я инициализировал модель, неверен. Я предполагаю, что нельзя использовать существующую модель представления, а затем ожидать, что она будет работать с плагином mapper. Таким образом, вместо этого вы инициализируете модель представления с необработанными данными JSON, используя ko.mapping.fromJS:
var helloWorldModel;
$(document).ready(function() {
var defaultData = {
name: 'Default Name',
message: 'Hello World Default'
};
helloWorldModel = ko.mapping.fromJS(defaultData);
ko.applyBindings(helloWorldModel);
$('#CallServerButton').click(getDataFromServer);
});
function getDataFromServer() {
$.getJSON("HelloSpring/SayJsonHello/chicken.json", function(data) {
mapServerData(data);
});
}
function mapServerData(serverData) {
alert(JSON.stringify(serverData));
ko.mapping.fromJS(serverData, helloWorldModel);
}
Этот код работает и обеспечивает ожидаемое поведение
Ответ 2
Вы не можете просто перезаписать свою модель, переназначив ее таким образом.
Когда вы выполните:
ko.applyBindings(helloWorldModel);
Вы говорите "привяжите модель helloWorldModel
к странице". Нокаут затем просматривает и подключает наблюдаемые в этой модели и связывает их со страницей.
Теперь, когда вы перезаписываете модель формы здесь:
helloWorldModel = ko.mapping.fromJS(serverData, helloWorldModel);
Это перезаписывает ваш объект модели с совершенно новым объектом с совершенно новыми наблюдаемыми в нем.
Чтобы исправить это, вам нужно просто изменить эту строку:
ko.mapping.fromJS(serverData, helloWorldModel);
Это касается свойств внутри модели и переназначает их для вас, не перезаписывая вашу модель.