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

https://www.nuget.org/packages/Knockout.Mapping