Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 没有初始数据/空表单的淘汰JS映射插件_Javascript_Knockout.js_Jqtouch_Knockout Mapping Plugin - Fatal编程技术网

Javascript 没有初始数据/空表单的淘汰JS映射插件

Javascript 没有初始数据/空表单的淘汰JS映射插件,javascript,knockout.js,jqtouch,knockout-mapping-plugin,Javascript,Knockout.js,Jqtouch,Knockout Mapping Plugin,我们正在使用knockout和knockout映射插件来促进jqtouchweb应用程序中的数据绑定。我们使用映射插件的原因是能够使用knockout,而无需在javascript中手动定义/更改viewmodels。当您有来自服务器/客户端数据库的初始数据负载时,映射插件工作得非常好 我们面临的问题是,我们有一些屏幕/视图,其形式可能没有任何初始数据。没有这些初始数据,映射插件就无法“生成”viewmodel(ko.mapping.fromJS)。这意味着我们仍然需要为大部分视图手动定义vie

我们正在使用knockout和knockout映射插件来促进jqtouchweb应用程序中的数据绑定。我们使用映射插件的原因是能够使用knockout,而无需在javascript中手动定义/更改viewmodels。当您有来自服务器/客户端数据库的初始数据负载时,映射插件工作得非常好

我们面临的问题是,我们有一些屏幕/视图,其形式可能没有任何初始数据。没有这些初始数据,映射插件就无法“生成”viewmodel(ko.mapping.fromJS)。这意味着我们仍然需要为大部分视图手动定义viewmodels


我是否错误地认为这是映射插件(应该)支持的场景?我的意思是,这意味着映射插件仅在您始终具有初始数据加载的场景中可用。

除了手动管理视图模型之外,还有一些选项供您选择。映射插件支持
create
回调,允许您自定义如何创建映射。如果碰巧缺少默认属性,则可以使用此选项向对象添加默认属性

大概是这样的:

另一种选择是使用绑定来创建缺少的属性。它可能看起来像:

//create an observable if it does not exist and populate it with the input's value
ko.bindingHandlers.valueWithInit = {
    init: function(element, valueAccessor, allBindingsAccessor, data) {
        var property = valueAccessor(),
            value = element.value;

        //create the observable, if it doesn't exist 
        if (!ko.isWriteableObservable(data[property])) {
            data[property] = ko.observable();
        }

        //populate the observable with the element's value (could be optional)
        data[property](value);

        ko.applyBindingsToNode(element, { value: data[property] });
    }
}
您可以这样使用它(需要将属性作为字符串传递,否则将出错):



这里的示例:

我认为问题的解决方案来自于以错误的方式思考视图模型。视图模型不仅是将数据传递到视图的东西,而且是将数据提交回视图的占位符

按照我通常使用knockout的方式,我从不向视图发送空视图模型。视图模型通常具有我绑定的所有字段。虽然它们可能是空字符串,或者是没有显示值的初始化对象,但实际的对象仍然存在,并且每个对象都有一个适当的表示形式,表示我绑定到的字段

您可能希望只向视图发送空对象,而不是什么都不发送

编辑:示例是un ASP.NET MVC

基本上,我在服务器端创建了一个视图模型对象,它包含了需要显示的所有数据以及需要收集的所有数据。为了更简单地验证代码,我通常将要收集的数据放入它自己的子类中,但这完全取决于代码的需要

在任何情况下,进入视图的any对象都来自vmBase类,该类基本上提供了一个toJSON()方法,该方法生成对象的JSON序列化。视图引擎在我的视图中调用它。如下面的代码所示

      <script type='text/javascript'>         
        var viewModel = ko.mapping.fromJS(<%= Model.ToJson() %>);                     

        $(document).ready( function () {        
            ko.applyBindings(viewModel);                             
        });                  
     </script>   

var viewModel=ko.mapping.fromJS();
$(文档).ready(函数(){
应用绑定(视图模型);
});                  
当我准备好发回代码时,我只需删除视图模型的JS版本

<script type='text/javascript'>
     var dataToSendToServer = ko.toJS(viewModel);
</script>

var dataToSendToServer=ko.toJS(viewModel);
在一些sanarios中,只有视图模型的一部分在更改(如果您正在进行AJAX更新),您可以做一些很酷的事情,比如切换模板,以便应用不同的绑定。在这种情况下,我们使用#ID_of_容器作为原始数据/模板的容器,并将模板(可包含数据绑定=“元素)替换为新模板ID_of_模板

<script type='text/javascript'>
    ko.cleanNode($("#ID_of_Container"));
    delete (viewModel.Some_Element_To_Be_Updated);
    viewModel = ko.mapping.updateFromJS(viewModel, New_Data_For_That_Element);

    // Use ko.toJS(viewModel) because standard template plugin doesn't understand 
    // knockout observables
    $("#ID_of_Container").html($("#ID_of_Template").tmpl(ko.toJS(viewModel)))
    ko.applyBindings(viewModel, $("#ID_of_Container")[0]);

</script>

ko.cleanNode($(“#ID_of_Container”);
删除(viewModel.要更新的某些元素);
viewModel=ko.mapping.updateFromJS(viewModel,该元素的新数据);
//使用ko.toJS(viewModel),因为标准模板插件不理解
//淘汰观测值
$(“#ID_of_Container”).html($(“#ID_of_Template”).tmpl(ko.toJS(viewModel)))
ko.applyBindings(viewModel,$(“容器的ID”)[0]);

我现在探索的一种方法是创建一个名为ReturnEmptyObject()的附加web服务方法,它除了在服务器端创建并返回一个新实例化的对象(其属性将是默认值)之外,什么都不做。(在我的例子中是C#)对象被序列化为JSON,最后到达jQuery Ajax调用。。。。然后传递到ko.mapping.updateFromJS()。。。这会在初始页面加载时创建所需的观察值。。。在调用ko.applyBindings()之前

当ko.applyBindings()执行时,它会找到所需的可观察对象,因此不会抛出错误,即使它们大部分是空的


通过这种方式,最初可以在不填写任何字段的情况下打开页面。但是,如果我在服务器端向类添加一些新属性,它们仍然会自动显示在客户端。

谢谢RP Niemeyer,我将在接下来的几天内尝试一下。听起来很有希望!custinit绑定对我来说非常有用,但是我不喜欢绑定中数据绑定属性的动态更新,所以我建议使用。类似:@ChrisDaMour-这个版本有点过时了。我使用自定义绑定更新了答案,该绑定将
绑定应用于元素,但不会覆盖任何其他绑定。另一种选择是只使用一个单独的
init
绑定,您将其放在任何其他绑定之前。@RPNiemeyer,这仍然是最好的方法吗?@GONeale-如果您想“动态”创建可观察对象,那么这仍然是一个很好的选择。您也在使用KO映射插件吗?这使您能够生成viewmodel,而不必“手动”定义它。这是我们遇到问题的部分。希望编辑有帮助。我花了一点时间才意识到我可以用击倒来做这类事情。但最终会有一些非常好的结果。It r
<script type='text/javascript'>
    ko.cleanNode($("#ID_of_Container"));
    delete (viewModel.Some_Element_To_Be_Updated);
    viewModel = ko.mapping.updateFromJS(viewModel, New_Data_For_That_Element);

    // Use ko.toJS(viewModel) because standard template plugin doesn't understand 
    // knockout observables
    $("#ID_of_Container").html($("#ID_of_Template").tmpl(ko.toJS(viewModel)))
    ko.applyBindings(viewModel, $("#ID_of_Container")[0]);

</script>