簡體   English   中英

將JavaScript放在部分視圖中是否可以

[英]Is it OK to put JavaScript in Partial Views

我正在使用Web應用程序,其中主頁面包含兩個部分:始終可見的常量塊和由3個部分視圖之一組成的信息塊。 每個部分視圖都作為AJAX請求的結果出現,並且只加載一次(在jquery提供切換窗口之后)。 它運作良好,但我遇到了一個問題。

部分視圖的html代碼包含在常量塊和info-block中使用的js函數。 當頁面加載時,這些函數可以“看到”彼此並且它可以工作,但是resharper找不到函數聲明並警告我這一點。 我無法通過將它們轉移到外部js文件來解決問題,因為razor語法可以在他們的代碼中找到。

我該怎么辦?

謝謝。

更新:

最后,我決定解決將js代碼與視圖分離的問題。 所以新的問題是如何將razor語法包含到js文件中或者什么是可接受的替代方案。 我發現的流行解決方案是使用全局變量,數據屬性和我更喜歡的解決方案 - John Katsiotis的RazorJS庫。

http://djsolid.net/blog/razorjs---write-razor-inside-your-javascript-files

我希望它能夠穩定運行並使Resharper感到高興。

干杯!

更新:

3年后,我回憶起這個問題,並決定根據我的經驗對其進行更新。 事實上,現在我寧願不建議使用額外的庫。 特別是如果您不是項目團隊中唯一的成員......如果您在所有庫中得到保證,它們會受到創建者和社區的支持,並且可以輕松集成到您的IDE中(例如,如果使用特殊語法) 。 你的團隊中的所有人都應該知道它是如何工作的。 所以現在我建議做下面的事情:

  1. 將所有JS保存在單獨的文件中。 盡可能地隔離它。 為它提供外部API。
  2. 從您的視圖中調用API函數。
  3. 將所有Razor生成的URL,文本消息,常量作為資源參數傳遞。

例如:

js文件:

$.api.someInitFunction = function(resources){ ... }

視圖:

<script>
    $.api.someInitFunction({
        urls: { myAction: '@Url.Action("MyAction", "MyController")' },
        messages: { error: '@errorMessage' },
        consts: { myConst: @myIntConst }
    });
</script>

如果Resharper警告你這不是什么大問題^ _ ^

但如果我是你,我根本不會把JavaScript放在局部視圖中

由於部分視圖可以多次插入一個頁面,因此您將遇到JavaScripts問題。

對於你的情況,如果你不能將JavaScript分成JS文件,那么只需創建另一個PartialView並將這些腳本放入其中,然后在主頁面中呈現它。

如果要編寫封裝了“小部件”的部分視圖,只要將它們包含在頁面中就可以工作,那么在部分視圖中嵌入腳本塊是將標記和初始化腳本封裝在局部視圖中的一種簡潔方法。 例如,我可能有一個名為“_EventList”的部分視圖,我在整個網站中使用它。 如果我放在我的母版頁上的兩個位置它應該工作,我不想在我的母版頁中編寫邏輯來初始化小部件。

如果您永遠不會在頁面中多次使用它,那么它很簡單。 但如果可能的話,請將腳本包裝起來,使其不會執行兩次。 見下文。 為了Stack Overflow片段,我通過在代碼片段中重復兩次局部視圖來模擬它,以表示在母版頁中包含兩次局部視圖。

我的母版頁可能如下所示:

<div id="left-nav">
   @Html.Partial("_EventList")           
</div>

<div id="body">
</div>

<div id="right-nav">
   @Html.Partial("_EventList")
</div>

例:

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- Self-contained partial view containing widget --> <div id="widgetDiv" class="panel panel-default"> <div class="panel-heading">Event Dates</div> <div class="panel panel-group"> <ul class="widget"> <!-- These will load dynamically --> </ul> </div> <script> $(document).ready(function() { // Run this once only in case widget is on page more than once if(typeof $widget == 'undefined') { $widget = $("ul.widget"); // could be more than one // mock data to simulate an ajax call var data = [ {Description: "March", StartDate: "03/01/2015"}, {Description: "April", StartDate: "04/01/2015"}, {Description: "May", StartDate: "05/01/2015"} ]; $.each($widget, function(w, widget) { // might be an $.ajax call $.each(data, function(i, row) { $(widget).append("<li><a href='/Widget/Search?startDate=" + row.StartDate + "'>" + row.Description + "</a></li>"); }); }); } }); </script> </div> <!-- End of widget / partial view --> <!-- Second copy of above for sake of example snippet --> <!-- No need to read further --> <!-- Self-contained partial view containing widget --> <div id="widgetDiv" class="panel panel-default"> <div class="panel-heading">Event Dates</div> <div class="panel panel-group"> <ul class="tinylist nav nav-sidebar widget"> <!-- These will load dynamically --> </ul> </div> <script> $(document).ready(function() { // Run this once only in case widget is on page more than once if(typeof $widget == 'undefined') { $widget = $("ul.widget"); // could be more than one // mock data to simulate an ajax call var data = [ {Description: "March", StartDate: "03/01/2015"}, {Description: "April", StartDate: "04/01/2015"}, {Description: "May", StartDate: "05/01/2015"} ]; $.each($widget, function(w, widget) { // might be an $.ajax call $.each(data, function(i, row) { $(widget).append("<li><a href='/Widget/Search?startDate=" + row.StartDate + "'>" + row.Description + "</a></li>"); }); }); } }); </script> </div> <!-- End of widget / partial view --> 

我同意Wahid的觀點,即你不應該在所有部分或其他方面將JavaScript放入視圖中。 我已經看到足夠的代碼來做到這一點,知道它只會導致無益。

我還要說你應該能夠將Razor語法中封裝的邏輯轉移到JavaScript中,你只需要將邏輯所需的信息傳遞給JavaScript。

我只是猜測下一條評論的經驗,但你應該像設計C#或VB.NET代碼的結構一樣設計JavaScript。 這樣你使用Razor的邏輯應該是你的JavaScript的一部分。

這樣你的JavaScript將更容易維護,我認為Resharper也應該更快樂。

我這樣做,發現它非常方便。 它適用於動態加載部分javascript片段以及ViewBag,HttpContext等的可用性。

它產生的感覺就像使用T4模板。

如果你添加像這樣的幻像腳本標簽,你甚至可以獲得javascript驗證,intellisense等。

@using System.Configuration
@if (false)
{
    @:<script type="text/javascript">
}    
        $scope.clickCartItem = function(cartItem) {
            console.log(cartItem);
            window.location.href =@Html.Raw("('" + ConfigurationManager.AppSettings["baseUrl"] + "/Checkout/' + cartItem.ItemId)");
        };
        dataAccess.getCart(
        function (response) {
            //...
        },
        function (response) {
            //...
        }
        );

@if (false)
{
    @:</script>
}

對於這個問題的未來觀眾,這是我的經驗。 我認為保留僅部分用於組織的部分腳本是個好主意。

我遇到的問題是在調試過程中,我有時會遇到斷點而無法解決問題,除非我將腳本移到父視圖中。 最有可能的原因是打印功能不止一次。 我希望部分能夠更好地解決和組織這些部分,但部分視圖中不支持部分(至少在MVC 4中不支持)。

所以我的答案是為了維護和調試,不應該在部分視圖中放入腳本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM