javascript - 包括特定于 ASP.NET MVC4 View 或部分 View 的脚本

标签 javascript asp.net-mvc vb.net asp.net-mvc-4 knockout.js

我看过很多类似于 How to add a script in a partial view in MVC4? 的问题和 MVC4 partial view javascript bundling Issue在涉及特定于 View 的脚本时,我仍在努力理解 ASP.NET MVC 体系结构。对于其他试图在其 MVC4 部分 View 中包含脚本的人来说,答案似乎是将脚本置于更高级别。但是有些脚本不能移动到更高的级别,它会在全局范围内运行。例如,我不想运行为未加载控件的 View 模型应用 knockout.js 数据绑定(bind)的脚本。而且我不想为每次加载页面时都不活跃的一大堆 View 运行一大堆脚本。

所以我开始在我的 .vbhtml View 中使用特定于 View 的 @Section Script block 来包含特定于 View 的脚本。但是,正如其他人指出的那样,这在部分 View 中不起作用。我正在对我们的架构进行原型(prototype)设计,以了解我们在这里可以做什么和不能做什么。我想在某些情况下,我可以将 View 用作局部 View ,反之亦然。但是,当您拉入 View 以用作局部 View 时,@Section Script block 不会呈现。我已经设法让我的所有 View 模型脚本以一种方式全局定义,这样我只需要运行一行代码来创建和绑定(bind) View 模型,但我仍然需要一行代码仅在特定 View 处于事件状态时运行.在局部 View 中,我可以在哪里适本地添加这行代码?

ko.applyBindings(window.webui.inventoryDetailViewModel(ko, webui.inventorycontext));

我走的路对吗?这是构建 MVC 应用程序的正确方法吗?

编辑 发现这个问题与我的问题密切相关,并且包括我的答案的重要部分:Can you call ko.applyBindings to bind a partial view?

最佳答案

下面是我编写 View 模型和 View 的方式:

// ~/scripts/app/viewModels/primaryViewModel.js
var primaryViewModelFactory = (function() {
    return { // this gives a singleton object for defining static members and preserving memory
        init: init
    }

    function init(values) {
        var model = {
            // initialization
            secondaryViewModel: secondaryViewModelFactory.init(values);
        }

        // I've decided to allow root-level view models to call apply bindings directly
        ko.applyBindings(model);
    }
}());

// ~/scripts/app/viewModels/secondaryViewModel.js
var secondaryViewModelFactory = (function() {
    return { 
        init: init
    }

    function init(values, target) {
        return = {
            // initialize object
        };
    }        
}());

在我的 View 中,我的主模板中确实有一个脚本部分。所以我的观点是这样的:

@section scripts {
    <script src="~/scripts/app/viewModels/....js"></script>
    $(function() {
        var vm = primaryViewModel.init(@Html.Raw(Json.Encode(Model)); 
    });
}

事实上,我编写这些 MVVM 应用程序的次数越多,我就越倾向于使用 ajax 加载数据,而不是将模型数据传递到 init 函数中。这使我能够将 init 调用移动到工厂中。那么你会得到类似的东西:

var primaryViewModelFactory = (function() {
    init();        

    function init(values) {
        var model = {
            // initialization
        }
        model.secondaryViewModel = secondaryViewModelFactory.init(values, model);

        // I've decided to allow root-level view models to call apply bindings directly
        ko.applyBindings(model);
    }
}());

这将我的 View 脚本缩减为一个简单的脚本标签:

@section scripts {
    <script src="~/scripts/app/viewModels/primaryViewModel.js"></script>        
}

最后,我喜欢在分部 View 中为 vm 组件创建脚本模板,如下所示:

部分 View 位于 ~/Views/Shared/ScriptTemplates/_secondaryViewModelTemplates.cshtml

<script src="@Url.Content("~/scripts/app/viewModels/secondaryViewModel.js")"></script>
<script id="secondary-view-model-details-readonly-template" type="text/html">...</script>
<script id="secondary-view-model-details-editor-template" type="text/html">...</script>
<script id="secondary-view-model-summary-template" type="text/html">...</script>

这里发生了一些事情。首先,导入相关脚本。这确保在呈现部分时包含必要的 View 模型工厂脚本。这允许主视图对子组件(可能有多个)的脚本需求一无所知。此外,通过在部分而不是脚本文件中定义模板,我们还能够利用非常有用的 HtmlHelper 和 UrlHelper 以及您选择的任何其他服务器端实用程序。

最后,我们在主视图中渲染模板:

@section scripts {
    @* primaryViewModel has a dependency on secondaryViewModel so the order does matter *@
    @Html.Partial("ScriptTemplates/_secondaryViewModelTemplates.cshtml")
    <script src="~/scripts/app/viewModels/primaryViewModel.js"></script>
}

<div data-bind="template: {name: 'secondary-view-model-details-editor-template', with: secondaryViewModel}"></div>

那是很多代码,而且都是用 SO 编写的,所以可能会有一些错误。在过去的几年里,我一直在改进这种 MVVM+MVC 架构风格,它确实改进了我的开发周期。希望这对您也有好处。我很乐意回答任何问题。

关于javascript - 包括特定于 ASP.NET MVC4 View 或部分 View 的脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21186505/

相关文章:

vb.net - 想要在不使用 Application.DoEvents 的情况下多次调用同一个 BackgroundWorker

mysql - 如何使用 VB.NET treeview 从 MySQL 作为数据库创建 TreeView

javascript - 如何使用 JSON 数据进行动态星级评分

javascript - 如何在kineticjs中分别使用draggable和click?

c# - 服务器无法在发送上传文件的 HTTP header 后附加 header

vb.net - 更改保存我的设置的路径 - VB.NET 2008

javascript - 使用 jQuery.each() 遍历两个数组?

javascript - asp.net hidefield.value 未由 javascript 更新

c# - 如何将多个文件与其他表单字段一起上传,ASP.NET MVC

jquery - JsonResult 对于 Jquery .ajax 返回 null