通过隐藏字段获得一个框架来处理knockout.js不持久化的问题
本文关键字:knockout 处理 框架 js 不持久 问题 持久化 一个 字段 隐藏 | 更新日期: 2023-09-27 18:12:52
- VS2013,WebForms,.NET 4.51
我想使用一个隐藏字段来跨回发维护Knock-Out视图模型的内容。所以我从http://knockoutjs.com/examples/cartEditor.html然后阅读http://www.codeproject.com/Articles/153735/Using-KnockoutJS-in-your-ASP-NET-applications一些想法。
最终结果如下:
<asp:HiddenField ID="HiddenField1" runat="server" />
<script type='text/javascript' src="http://knockoutjs.com/examples/resources/sampleProductCategories.js"></script>
<script type="text/javascript">
function formatCurrency(value) {
return "$" + value.toFixed(2);
}
var CartLine = function () {
var self = this;
self.category = ko.observable();
self.product = ko.observable();
self.quantity = ko.observable(1);
self.subtotal = ko.computed(function () {
return self.product() ? self.product().price * parseInt("0" + self.quantity(), 10) : 0;
});
// Whenever the category changes, reset the product selection
self.category.subscribe(function () {
self.product(undefined);
});
};
var Cart = function () {
// Stores an array of lines, and from these, can work out the grandTotal
var self = this;
self.lines = ko.observableArray([new CartLine()]); // Put one line in by default
self.grandTotal = ko.computed(function () {
var total = 0;
$.each(self.lines(), function () { total += this.subtotal() })
return total;
});
// Operations
self.addLine = function() {
self.lines.push(new CartLine());
SaveList();
};
self.removeLine = function(line) {
self.lines.remove(line);
SaveList();
};
self.save = function () {
var dataToSave = $.map(self.lines(), function (line) {
return line.product() ? {
productName: line.product().name,
quantity: line.quantity()
} : undefined
});
alert("Could now send this to server: " + JSON.stringify(dataToSave));
};
self.SaveList = function () {
var myHidden = document.getElementById('<%= HiddenField1.ClientID %>');
if (myHidden)//checking whether it is found on DOM, but not necessary
{
var dataToSave = $.map(self.lines(), function (line) {
return line.product() ? {
productName: line.product().name,
quantity: line.quantity()
} : undefined;
});
alert("Saving - " + JSON.stringify(dataToSave));
myHidden.value = JSON.stringify(dataToSave);
}
};
};
var stringViewModel = document.getElementById('<%=HiddenField1.ClientID %>').value;
var viewModel;
if (document.getElementById('<%=HiddenField1.ClientID %>').value == '') {
alert('Nothing In Hidden Field');
viewModel = new Cart();
} else {
viewModel = ko.utils.parseJson(stringViewModel);
for (var propertyName in viewModel) {
viewModel[propertyName] = ko.observable(viewModel[propertyName]);
}
}
ko.applyBindings(viewModel);
$(document.forms[0]).submit(function () {
alert('In Submit');
viewModel.SaveList();
});
</script>
所以基本上,当页面加载时,我们会创建一个新的Cart实例。当表单发布后,我们成功地将购物车序列化到HiddenField1,我可以在后面的代码中看到预期值:
protected void btnSave_OnClick(object aSender, EventArgs aE)
{
if (HiddenField1.Value == null)
{
}
}
但是,回发后stringViewModel的内容
var stringViewModel = document.getElementById('<%=HiddenField1.ClientID %>').value;
总是blanl/空的?为什么?
然后假设我有正确的JSON,下面是将其应用回视图模型的正确方法吗?
viewModel = ko.utils.parseJson(stringViewModel);
for (var propertyName in viewModel) {
viewModel[propertyName] = ko.observable(viewModel[propertyName]);
}
编辑:我尝试了一些没有运气的东西
- 将所有JS代码添加到jQuert OnReady((处理程序
- 尝试使用而不是ASP:HiddenField
在PostBack中的所有情况下,我都可以看到SaveList((为隐藏字段分配的值,但当页面再次显示时(回发后(,隐藏字段的值是一个空字符串
对于第一部分,您所做的是正确的。使用控制台(在浏览器中按F12(检查隐藏字段,并检查它是否具有值。如果您在服务器端看到它,那么它应该在客户端。您还可以运行js代码,并设置断点来发现问题所在。您还可以在服务器端添加PreRender处理程序,并添加断点和调试来检查服务器端是否没有删除Value(此事件发生在页面呈现为发送到浏览器之前(。
对于第二部分,最快的方法是使用敲除映射,它从JavaScript对象或JSON创建模型。您需要使用以下内容:ko.mapping.fromJSON
。这将从JSON创建一个新的视图模型,您可以直接绑定它。(正如您在文档中所读到的,您可以自定义视图模型的创建方式(。
然而,你所做的却很奇怪。您通常将Knockout与Web API、Web服务或Page方法一起使用,而无需重新加载页面。模型是通过其中一种技术,使用AJAX来恢复、更新、更改等的。