ASP.NET MVC 将模型传递给 KnockoutJS 外部文件
ASP.NET MVC pass model to KnockoutJS external file
我在 Whosebug 上和通过 Google 搜索阅读了很多资源,但似乎没有什么特别适合我的问题。
tl;dr 我想将我的 C# 模型从我的视图传递到外部 JS 文件 (Knockout),这样我就可以使用模型中的数据显示在我的视图上.
更多信息:
我有一个非常标准的 ASP.NET MVC 5 项目,其中包含(例如)1 个视图、1 个控制器和一个检索的 C# 视图模型,并在我的 C# 控制器中操作数据。我的外部 JavaScript 文件包含 Knockout 代码,特别是我想将该 C# 模型放入该外部 JS 文件中的 observableArray 中,这样我就可以将我的 Knockout 代码隐藏在我的视图之外(可能除了几行之外)。
示例:
books.js
var app = (function (app) {
app.FilterBooks = function () {
var self = this,
books = ko.observableArray(myC#Model);
var data = [];
self.BooksList = ko.computed(function(){
ko.utils.arrayForEach(books(), function (item) {
data.push(item);
});
});
return data;
};
return app;
}(app || {}));
myC#Model
是我要从视图(或控制器)中检索的 C# 模型。
Index.html
@model viewModel
<div data-bind="foreach: BooksList">
some knockout code in the view
<p data-bind="text: bookName"></p>
</div>
@section scripts{
<script type="text/javascript">
$(document).ready(function () {
var e = new app.FilterBooks;
ko.applyBindings(e);
});
</script>
}
HomeController.cs
public ActionResult Index()
{
//gets the list of all the books
var viewModel = this.bookManager.GetAllBooks();
return View(viewModel);
}
想法:
我想到的一个解决方案是创建一个全局变量,然后我就可以在之后引用的任何 JS 文件中访问它,但这个解决方案似乎不太理想。在我看来,这方面的一个例子是:window.booksVM = @Html.Raw(Json.Encode(Model));
我希望有一个更好、更具可扩展性的解决方案,包括在视图中获取模型并能够在我的外部 JS 文件中访问该模型。
序列化您的模型并将其传递给您的视图模型。
使用 ko.mapping
将其从您的模型动态映射到您的视图模型中。
假设您的 collection 包含一个 books 数组,它将自动成为一个可观察数组。
查看模型
var app = (function (app) {
app.FilterBooks = function (data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
};
return app;
}(app || {}));
索引js
<script type="text/javascript">
$(document).ready(function () {
var data = @Html.Raw(Json.Encode(Model));
var e = new app.FilterBooks(data);
ko.applyBindings(e);
});
</script>
更新
同样如@james14 所述,请确保包含映射插件。
http://knockoutjs.com/documentation/plugins-mapping.html
PM> Install-Package Knockout.Mapping
我在 Whosebug 上和通过 Google 搜索阅读了很多资源,但似乎没有什么特别适合我的问题。
tl;dr 我想将我的 C# 模型从我的视图传递到外部 JS 文件 (Knockout),这样我就可以使用模型中的数据显示在我的视图上.
更多信息:
我有一个非常标准的 ASP.NET MVC 5 项目,其中包含(例如)1 个视图、1 个控制器和一个检索的 C# 视图模型,并在我的 C# 控制器中操作数据。我的外部 JavaScript 文件包含 Knockout 代码,特别是我想将该 C# 模型放入该外部 JS 文件中的 observableArray 中,这样我就可以将我的 Knockout 代码隐藏在我的视图之外(可能除了几行之外)。
示例:
books.js
var app = (function (app) {
app.FilterBooks = function () {
var self = this,
books = ko.observableArray(myC#Model);
var data = [];
self.BooksList = ko.computed(function(){
ko.utils.arrayForEach(books(), function (item) {
data.push(item);
});
});
return data;
};
return app;
}(app || {}));
myC#Model
是我要从视图(或控制器)中检索的 C# 模型。
Index.html
@model viewModel
<div data-bind="foreach: BooksList">
some knockout code in the view
<p data-bind="text: bookName"></p>
</div>
@section scripts{
<script type="text/javascript">
$(document).ready(function () {
var e = new app.FilterBooks;
ko.applyBindings(e);
});
</script>
}
HomeController.cs
public ActionResult Index()
{
//gets the list of all the books
var viewModel = this.bookManager.GetAllBooks();
return View(viewModel);
}
想法:
我想到的一个解决方案是创建一个全局变量,然后我就可以在之后引用的任何 JS 文件中访问它,但这个解决方案似乎不太理想。在我看来,这方面的一个例子是:window.booksVM = @Html.Raw(Json.Encode(Model));
我希望有一个更好、更具可扩展性的解决方案,包括在视图中获取模型并能够在我的外部 JS 文件中访问该模型。
序列化您的模型并将其传递给您的视图模型。
使用 ko.mapping
将其从您的模型动态映射到您的视图模型中。
假设您的 collection 包含一个 books 数组,它将自动成为一个可观察数组。
查看模型
var app = (function (app) {
app.FilterBooks = function (data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
};
return app;
}(app || {}));
索引js
<script type="text/javascript">
$(document).ready(function () {
var data = @Html.Raw(Json.Encode(Model));
var e = new app.FilterBooks(data);
ko.applyBindings(e);
});
</script>
更新
同样如@james14 所述,请确保包含映射插件。
http://knockoutjs.com/documentation/plugins-mapping.html
PM> Install-Package Knockout.Mapping