因此,如果你的Controller Action返回一个带有预先填充值的模型,你如何让KnockoutJS知道它们?
E.g:
@Html.TextBoxFor(m => m.Title, new { data_bind="value: title"} )
但是,在绑定knockout.js ViewModel的$(document).ready()
上,此值尚未填充:
$(document).ready({
var viewModel = {
title: ko.observable($("#Title").val()) // too early for this?!
}
ko.applyBindings(viewModel);
});
你如何让KnockoutJS与MVC的模型绑定一起工作? 我找到的一个解决方法是在我的Razor View中设置JavaScript变量,如下所示:
<script>
var strTitle = '@Model.Title';
</script>
而不是在Knockout模型绑定中使用它。这有效,但我讨厌它。如果您的表单有数百个字段怎么办?您不希望页面中包含任意数量的JavaScript变量。 我错过了明显的吗?
答案 0 :(得分:3)
这似乎与this question类似。通常,您可以通过在脚本中将@Model转换为JSON来设置视图模型:
<script type="text/javascript">
var model = @(new HtmlString(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model)));
</script>
您还可以创建自己的绑定处理程序,该处理程序最初将根据控件值加载视图模型。这个新的myvalue
处理程序基本上调用现有的value
处理程序,除了它从初始控制值更新视图模型。
ko.bindingHandlers['myvalue'] = {
'init': function (element, valueAccessor, allBindingsAccessor) {
// call existing value init code
ko.bindingHandlers['value'].init(element, valueAccessor, allBindingsAccessor);
// valueUpdateHandler() code
var modelValue = valueAccessor();
var elementValue = ko.selectExtensions.readValue(element);
modelValue(elementValue); // simplified next line, writeValueToProperty isn't exported
//ko.jsonExpressionRewriting.writeValueToProperty(modelValue, allBindingsAccessor, 'value', elementValue, /* checkIfDifferent: */ true);
},
'update': function (element, valueAccessor) {
// call existing value update code
ko.bindingHandlers['value'].update(element, valueAccessor);
}
};
然后当你调用ko.applyBindings时,你的observable最初将根据控件的值设置:
<input type="text" data-bind="myvalue: Title" value="This Title will be used" />
<input type="text" data-bind="value: Title" value="This will not be used" />
<!-- MVC -->
@Html.TextBoxFor(m => m.Title, new { data_bind="myvalue: Title"} )
答案 1 :(得分:2)
如何使用JSON.NET或类似方法将整个页面模型序列化为json。然后,您的页面将通过非js用户的普通剃刀视图绑定进行填充。然后您的页面脚本可以是:
<script>
ko.applyBindings(@Html.ToJSON(Model));
</script>
或者,如果您有一个类型化的viewModel
<script>
var viewModel = new MyViewModel(@Html.ToJSON(Model));
ko.applyBindings(viewModel);
</script>
将客户端和实际视图模型结构相同是有意义的,因此不需要对json形状进行操作。
修改强>
toJSON助手的示例。
public static MvcHtmlString ToJson(this HtmlHelper html, object obj)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return MvcHtmlString.Create(serializer.Serialize(obj));
}
希望这有帮助。
答案 2 :(得分:2)
因为我没有给Jason Goemaat answer添加评论50分的声誉,所以我决定在此处添加我的评论作为答案。
所有学分归Jason Goemaat所有。
我无法让代码对我有用。所以我不得不做一个小改动。
ko.bindingHandlers['myvalue'] = {
'init': function (element, valueAccessor, allBindingsAccessor) {
//get initial state of the element
var modelValue = valueAccessor();
var elementValue = ko.selectExtensions.readValue(element);
// call existing value init code
ko.bindingHandlers['value'].init(element, valueAccessor, allBindingsAccessor);
//Save initial state
modelValue(elementValue);
},
'update': function (element, valueAccessor) {
// call existing value update code
ko.bindingHandlers['value'].update(element, valueAccessor);
}
};
如果我在顶部有这条线,
// call existing value init code
ko.bindingHandlers['value'].init(element, valueAccessor, allBindingsAccessor);
它正在删除元素的原始状态。所以无论我在输入字段中有什么价值,它都被删除了。
在模型中我有这个:
//publishing comment
self.publishingComment = ko.observable();
我的MVC看起来像这样
@Html.TextBoxFor(model => model.Comment, new { data_bind = "myvalue: publishingComment" })