2012-01-26 24 views
1

我使用EditorTemplates來處理諸如DateTime,Colors等東西。我的表單可能包含相當多的這些模板,它們主要通過Ajax作爲局部視圖加載。通過Ajax加載的ASP.NET MVC3 EditorTemplates沒有複製jQuery?

而不是在每個編輯器模板的底部有一堆jQuery初始化腳本,有沒有一種概念性的方式來做它每個響應只有一次?比方說,你有10個日期時間選擇器,在一個表單中,傳遞相同的初始化代碼10次真的很愚蠢。

使用10日期選擇器將初始化腳本放置在主窗體上會很有效(當然,將代碼隔離到日期時間編輯器模板並沒有多大作用),但是在其他情況下,您可能只想擁有一個日期時間選擇器使用不同的表單或兩到三個,現在您可以在代碼中的多個視圖中複製這些腳本。

那麼我怎麼能仍然在這裏利用編輯器模板正確的方式?我想我正在尋找類似的東西 -

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

添加到通過AJAX渲染的部分景色的作品編輯模板的底部。

回答

1

一件事我們做了我們的項目是具有延伸配置之類的東西,利用數據不顯眼的JavaScript的模式屬性一個startup.js文件。我們的例子是按鈕。比方說,我有以下的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擴展輕鬆地填寫我們需要/使用的資料的數據屬性。

+0

謝謝。然後我拿它通過ajax呈現的東西,然後您必須再次調用initializebuttons,並在視圖底部使用簡單的? – psy

+0

nope ... $(document).ready(initializeButtons).ajaxSuccess(initializeButtons)'在文檔就緒**和** ajax成功時調用'initializeButtons'。 –

+0

有趣。我喜歡這個。在初始響應之前,我開始沿着將所有內容移動到.js文件的路徑,然後在每個分部視圖的末尾調用一個函數來傳遞選擇器以初始化該項目。在每個Ajax調用之後調用這個函數是否有任何性能問題(可能有10個用於不同類型的編輯器/ UI對象)? – psy

2

那麼我怎麼還能在這裏利用編輯器模板?我 認爲我正在尋找類似 - EnsureThisScriptIsOutputOncePerThisResponse()添加到編輯器模板的底部 。

使用Cassette。這是允許您從任何地方引用腳本和樣式表的庫,甚至可以從部分視圖中引用。然後,它確保腳本引用順序並呈現腳本,以確保此腳本及其引用僅輸出一次,並且通常在單個地方響應。

更新:

阿賈克斯引用的腳本可以做如下

在日期選擇器編輯模板 - EditorTemplates/DateTime.cshtml

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

而且在日期選擇器容器的形式,直接呈現腳本。如果沒有AJAX,這將是在佈局網頁做

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

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

感謝您的鏈接。我不相信Cassette會使用通過Ajax呈現的部分視圖。 – psy

+0

它肯定有效。我今天就是這麼做的:)。 ajax的結果是什麼?它是一塊html,它可以包含腳本標記,並且這些腳本將被執行。看到我的更新 – archil

1

您可以使用livequery插件將初始化代碼添加到外部.js文件並將文件包含在_Layout.cshtml中。

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

我用一個初始化屬性OM需要一些腳本運行的東西:

<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); }); 
});