Есть ли способ, чтобы отображение заполняло свойство модели асинхронно и обновляло представление автоматически? - PullRequest
1 голос
/ 13 февраля 2012

Я пытаюсь загрузить значения для свойства модели через AJAX, но по завершении AJAX представление не обновляется.

Я использую нокаут 2.0.0 и отображение нокаута 2.0.3.

jsFiddle:

http://jsfiddle.net/rsfTy/

HTML:

<p>Code: <span data-bind="text: item.code"></span></p>
<p>Value: <span data-bind="text: item.value"></span></p>

JavaScript:

var ViewModel = function () {
    var self = this;

    self.item = ko.mapping.fromJS({ "code": "123" });

    self.load = function () {
        jQuery.ajax({
            "success": function () {
                ko.mapping.fromJS({ "value": "abc" }, {}, self.item);
            },
            "url": "/echo/json"
        });            
    };

    self.load();
};

ko.applyBindings(new ViewModel());

В этом примере отображается значение item.code, поскольку оно определяется при инициализации модели представления, но значение item.value никогда не отображается, поскольку заполняется асинхронно.

Я уже пробовал различные комбинации ko.observable и ko.mapping.fromJS, как для инициализации, так и для обновления свойств, но безрезультатно.

Я хотел бы избежать - если возможно - инициализировать все свойства item вручную.

Я также знаю, что могу переместить ko.applyBindings в success вызова AJAX, но у меня есть несколько таких свойств, как это, и для этого мне придется реализовать систему очередей, которая является избыточным.

Что я делаю не так? Как правильно это сделать?

1 Ответ

3 голосов
/ 13 февраля 2012

Когда вы выполняете начальное сопоставление, не будет видимых «значений», с которыми пользовательский интерфейс будет связываться. Таким образом, когда вы выполняете обновление через подключаемый модуль сопоставления, он создает наблюдаемое «значение», но это слишком поздно (поскольку пользовательский интерфейс уже прошел привязку).

Если вы инициализируете его следующим образом: self.item = ko.mapping.fromJS({ "code": "123", "value": "" });, тогда он будет работать правильно.

...