Javascript 没有初始数据/空表单的淘汰JS映射插件
我们正在使用knockout和knockout映射插件来促进jqtouchweb应用程序中的数据绑定。我们使用映射插件的原因是能够使用knockout,而无需在javascript中手动定义/更改viewmodels。当您有来自服务器/客户端数据库的初始数据负载时,映射插件工作得非常好 我们面临的问题是,我们有一些屏幕/视图,其形式可能没有任何初始数据。没有这些初始数据,映射插件就无法“生成”viewmodel(ko.mapping.fromJS)。这意味着我们仍然需要为大部分视图手动定义viewmodelsJavascript 没有初始数据/空表单的淘汰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
我是否错误地认为这是映射插件(应该)支持的场景?我的意思是,这意味着映射插件仅在您始终具有初始数据加载的场景中可用。除了手动管理视图模型之外,还有一些选项供您选择。映射插件支持
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>