使用异步获取的数据填充KnockoutJS支持的表单的惯用方法是什么?

时间:2013-08-14 13:08:24

标签: javascript mvvm knockout.js idioms

使用HTTP GET从服务器异步获取的数据填充KnockoutJS支持的表单的惯用方法是什么?我遇到的问题是,如果我不创建域模型的空虚拟实例(请参阅下面的代码),Knockout会因为尝试为表单调用domainModel().namedomainModel().description而中断$.getJSON来电之前的字段已完成。

处理这种情况的常用方法是什么?我应该首先执行$.getJSON并在成功回调中调用ko.applyBindings(new ViewModel(domainModelData));还是有其他方式?

HTML&内联Javascript:

<form data-bind="submit: update">
    <input id="name" data-bind="value: domainModel().name"/>
    <input id="description" data-bind="value: domainModel().description"/>
    <button type="submit"/>     
</form>


<script type="text/javascript">
    $(document).ready(function () {
        ko.applyBindings(new ViewModel());
    });
</script>

Knockout视图模型:

function DomainModel(data) {
    var self = this;
    self.id = ko.observable(data.id);
    self.name = ko.observable(data.name);
    self.description = ko.observable(data.description);
}

function ViewModel() {
    var self = this;

    // This feels somehow dirty
    self.domainModel = ko.observable(new DomainModel({id: null, name: "", description: ""}));

    self.update = function() {
        ...
    };

    $.getJSON("domainModel/<id>", function(domainModelData) {
        self.domainModel(new DomainModel(domainModelData));
    });
}

1 个答案:

答案 0 :(得分:2)

您应该使用with binding或foreach绑定来确保在绑定尝试解析之前对象存在 -

<form data-bind="submit: update, with: domainModel">
    <input id="name" data-bind="value: name"/>
    <input id="description" data-bind="value: description"/>
    <button type="submit"/>     
</form>

基本上,在domainModel具有值名称之前,将不会解析描述。另一种方法是使用$ data。前缀说'如果没有数据,请等到有'

<form data-bind="submit: update">
    <input id="name" data-bind="value: $data.domainModel().name"/>
    <input id="name" data-bind="value: $data.domainModel().description"/>
    <button type="submit"/>     
</form>
相关问题