ASP.NET MVC3 EditorTemplates通过Ajax加载没有复制jQuery?

时间:2012-01-26 14:46:10

标签: jquery ajax asp.net-mvc mvc-editor-templates

我正在使用EditorTemplates来处理DateTime,Colors等等。我的表单可能包含相当多的这些模板,主要通过Ajax作为局部视图加载。

不是在每个编辑器模板的底部都有一堆jQuery初始化脚本,是否有一种概念性的方法,每次响应只执行一次?让我们说你有10个日期时间选择器,在一个表单上,传递相同的初始化代码10次真的很愚蠢。

将初始化脚本放在带有10个日期选择器的主窗体上会很有效(当然不会将代码与日期时间编辑器模板隔离开来),但是在其他情况下你可能只想拥有一个日期时间选择器在不同的表单上或两个或三个,现在您在代码中的多个视图中复制这些脚本。

那么我怎么能在这里以正确的方式利用编辑器模板呢?我想我正在寻找像 -

这样的东西
EnsureThisScriptIsOutputOncePerThisResponse(<script>$('.datepicker').datepicker("insert lengthy config here");</script>)

添加到编辑器模板的底部,该模板适用于通过AJAX呈现的部分视图。

4 个答案:

答案 0 :(得分:2)

  

那么我怎么能在这里以正确的方式利用编辑器模板呢?一世   我想我正在寻找类似的东西 -   确保将ThisScriptIsOutputOncePerThisResponse()添加到底部   编辑器模板。

使用Cassette。这是一个允许您从任何地方引用脚本和样式表的库 - 甚至是部分视图。然后它确保脚本引用顺序并呈现脚本,确保此脚本及其引用仅输出一次,并且通常在单个位置作为响应。

<强>更新

引用ajax的脚本可以按如下方式完成

在datepicker编辑器模板中 - EditorTemplates / DateTime.cshtml

@model DateTime?
@{
    Bundles.ReferenceScript("path to datepicker script. Script may reference jquery ui in its turn");
} 
//datepicker

在datepicker容器表单中,直接渲染脚本。如果不是ajax,这将在布局页面

中完成
@model ViewModelModelWithTenDates
@Bundles.RenderScripts() //will output distinc script references in order

//10 datepickers
@Html.EditorFor(model => model.FirstDate)

答案 1 :(得分:1)

我们在项目中做的一件事是拥有一个startup.js文件,该文件通过利用数据属性来配置类似的东西来扩展不显眼的javascript模式。我们的一个例子是按钮。假设我有以下html:

<input type='submit' data-button=true data-button-icon='ui-icon-check' value='approve' />

启动文件会查找类似这样的按钮:

function initializeButtons() {
    $("*[data-button=true]").each(function () {
        var $this = $(this);
        var initialized = $this.data('button-init');
        if (!initialized) {
            var options = {
                disabled: $this.data('button-disabled'),
                text: $this.data('button-text'),
                icons: {
                    primary: $this.data('button-icon-primary') || $this.data('button-icon'),
                    secondary: $this.data('button-icon-secondary')
                }
            };
            $this.button(options);
            $this.data('button-init', true);
        }
    });
}

$(document).ready(initializeButtons).ajaxSuccess(initializeButtons)

这使得常见的jQuery UI初始化代码更易于管理,我们创建了HtmlHelper扩展,以便轻松填写我们需要/使用的内容的数据属性。

答案 2 :(得分:1)

您可以使用livequery插件将初始化代码添加到外部.js文件中,并将该文件包含在_Layout.cshtml中。

$(".datepicker").livequery(function(){
    $(this).datepicker("insert lengthy config here");
});

答案 3 :(得分:1)

我使用init属性和需要运行脚本的东西:

<input type="text" id="id" init="datepicker makereadonly" />

这表示必须运行两个函数。运行它们是在Ajax-complete中完成的,它在外部文件中定义,请注意,一旦项目被初始化,就会设置初始化属性。这样,部分视图中就不存在脚本。

var initFunctions = initFunctions || {};

initFunctions.datepicker = function(item) {
    $(item).datepicker();
};

initFunctions.readonly = function(item) {
    $(item).attr("disabled", "disabled");
};

$('body').ajaxComplete(function (e, xhr, settings) {
  var itemFunction = function (item) {
     var $this = $(item);
     var attr = $this.attr("init");
     var functions = attr.split(" ");
     for (var i = 0; i < functions.length; i++) {
        var funcName = functions[i];
        var func = initFunctions[funcName];
        if (func != undefined)
           func($this);
     }
     $this.attr("initialized", "");
  };

  items = $("[init]:not([initialized])");
  items.each(function (index, item) { itemFunction(item); });
});