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

Javascript 用异步获取的数据填充KnockoutJS支持的表单的惯用方法是什么?,javascript,mvvm,knockout.js,idioms,Javascript,Mvvm,Knockout.js,Idioms,使用HTTP GET从服务器异步获取的数据填充KnockoutJS支持的表单的惯用方法是什么?我遇到的问题是,如果我不创建域模型的空虚拟实例(请参见下面的代码),则会出现敲除,因为它试图在$.getJSON调用完成之前调用表单字段的domainModel().name和domainModel().description 处理这种情况的常见方法是什么?我是否应该首先执行$.getJSON并调用ko.applyBindings(新的ViewModel(domainModelData))在成功回调中,

使用HTTP GET从服务器异步获取的数据填充KnockoutJS支持的表单的惯用方法是什么?我遇到的问题是,如果我不创建域模型的空虚拟实例(请参见下面的代码),则会出现敲除,因为它试图在
$.getJSON
调用完成之前调用表单字段的
domainModel().name
domainModel().description

处理这种情况的常见方法是什么?我是否应该首先执行
$.getJSON
并调用
ko.applyBindings(新的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>
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));
    });
}

$(文档).ready(函数(){
应用绑定(新的ViewModel());
});
淘汰视图模型:

<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>
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));
    });
}
函数域模型(数据){
var self=这个;
self.id=ko.可观察(data.id);
self.name=ko.observable(data.name);
自我描述=可观察(数据描述);
}
函数ViewModel(){
var self=这个;
//这感觉有点脏
self.domainModel=ko.observable(新的domainModel({id:null,name:,description:”“}));
self.update=函数(){
...
};
$.getJSON(“domainModel/”,函数(domainModelData){
domainModel(新的domainModel(domainModelData));
});
}

在绑定尝试解析之前,应使用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>


谢谢,这回答了我的问题。如果我希望在填充之前显示空表单,或者甚至允许未填充表单,但应由用户从头开始填充,该怎么办?目前,如果domainModel从未被填充,表单将根本不会显示。我想这需要空的DomainModel实例?您的意思是在表单中显示空元素(输入)并在加载DomainModel后应用绑定?这很简单,让我更新我的答案以包括虚拟机编辑---查看代码后,唯一需要更改的是为ID分配一个虚拟值,使其工作,或者对任何未定义或空的值使用$data.domainModel().ID方法。好的,我收回我以前的注释,您不需要设置ID,因为您在视图中没有绑定到它,因此,您可以将其保留为空,让服务器分配一个ID,或者自己执行逻辑分配一个ID。在调用getJSON之前,视图模型将创建一个空的DomainModel对象,因此它应该可以正常工作。