1

我将 EditorTemplates 用于 DateTime、Colors 等。我的表单可能包含相当多的这些模板,主要是通过 Ajax 作为局部视图加载的。

与其在每个编辑器模板的底部都有一堆 jQuery 初始化脚本,有没有一种概念性的方法可以让每个响应只执行一次?假设您有 10 个日期时间选择器,在一个表单上,传递相同的初始化代码 10 次真的很愚蠢。

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

那么我怎样才能在这里以正确的方式利用编辑器模板呢?我想我正在寻找类似的东西——

EnsureThisScriptIsOutputOncePerThisResponse(<script>$('.datepicker').datepicker("insert lengthy config here");</script>)

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

4

4 回答 4

2

那么我怎样才能在这里以正确的方式利用编辑器模板呢?我想我正在寻找类似的东西—— EnsureThisScriptIsOutputOncePerThisResponse() 添加到编辑器模板的底部。

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

更新:

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)
于 2012-01-26T14:50:41.937 回答
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 扩展来轻松填充我们需要/使用的东西的数据属性。

于 2012-01-26T15:50:40.130 回答
1

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

$(".datepicker").livequery(function(){
    $(this).datepicker("insert lengthy config here");
});
于 2012-01-26T16:30:14.443 回答
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); });
});
于 2012-01-31T07:03:59.913 回答