2012-06-19 36 views
46

我正在開發Web應用程序,其中主頁面包含兩部分:始終可見的常量塊和由3個部分視圖中的一個構成的信息塊。每個局部視圖都是AJAX請求的結果,並且只加載一次(在jQuery提供切換窗口之後)。它運行良好,但我遇到了一個問題。是否可以在部分視圖中放入JavaScript

部分視圖的html代碼包含常量塊和信息塊中使用的js函數。當頁面被加載時,這些函數可以「看到」對方,它的工作原理,但resharper無法找到函數聲明,並警告我這一點。由於可以在代碼中找到剃刀語法,我無法通過將它們轉移到外部js文件來解決問題。

我該怎麼辦?

謝謝。

更新:

最後我決定從解決意見分開我的js代碼的問題。所以,新的問題是如何將剃刀語法包含到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> 
+0

我不能決定什麼答案是更有用的我:) – Tomy

+0

感謝和歡迎到Stackoverflow :) –

+0

這是一個愉快的開始這樣一個不錯的接待,非常感謝! – Tomy

回答

27

如果ReSharper的警告您這不是什麼大不了的^ _^

但如果我是你,我不會把JavaScript放入部分視圖在所有

由於部分視圖可能會多次插入到一頁中,因此您會在JavaScript中遇到問題。

對於您的情況,如果您無法將JavaScript分離爲JS文件,那麼只需即可創建另一個PartialView,並將這些腳本放入其中並將其呈現在主頁面中。

+0

謝謝,瓦希德! 但有時候Resharper代碼真的比我更好:) 事實上,我知道將js放入部分視圖並不是一個好主意。但正如我所說,在我的網頁上,它們存在於一個副本中,所以例如嵌套只是「不可能的」。 遵循你關於腳本部分視圖的建議,我將使主視圖非常好。但遺憾的是RenderPartial沒有解決Resharper問題。我可以錯了嗎? – Tomy

+3

如果這是一個小應用程序,並且您不想花費更多時間,那麼請保持您的工作。但是如果你在談論「編程習慣」,那麼你應該將你的JavaScript和Views分開。 –

+0

對於'@ Html.ActionLink(...)'有很多解決方案,但不是將JavaScript直接放在PartialView中。你可以看看這個答案http://stackoverflow.com/a/3789959/105445 –

3

我同意瓦希德,你不應該把JavaScript放在所有部分或其他地方的視圖中。我見過足夠的代碼,知道它只會導致不好的結果。

我也會說你應該能夠將Razor語法封裝的邏輯轉換成JavaScript,你只需要將你的邏輯所需的信息傳遞給你的JavaScript。

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

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

+0

感謝您的回答! 但問題不在於邏輯。我使用Razor來建立鏈接(例如Url.Action)和類似的東西。把它們作爲參數傳遞給我看起來很奇怪。 – Tomy

+0

對於鏈接,您仍然可以將它們放在href上,只需使用preventDefault。此外,html5數據屬性在這些情況下也很有用。看看dojo或yui3,看看這些庫是如何構建的。 – eaglestorm

+0

有用的功能,謝謝! – Tomy

1

我這樣做,發現它非常方便。它可以很好地動態加載部分JavaScript代碼片段的可用性ViewBag,HttpContext等。

它導致感覺像使用T4模板。

如果您添加像這樣的幻影腳本標籤,您甚至可以獲得JavaScript驗證,智能感知等。

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

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

如果你想寫一個封裝「小工具」,只是工作,一旦你將它們包含在一個頁面,然後嵌入局部視圖內的腳本塊局部視圖是一個乾淨的方式來包裝標記和初始化腳本在局部視圖中一起使用。例如,我可能會在我的網站中使用名爲「_EventList」的部分視圖。如果我在我的母版頁上放置兩個地方,它應該只是工作,我不想在我的母版頁中編寫邏輯來初始化小部件。

如果你永遠不會在頁面中多次使用它,它很簡單。但是,如果你可能,然後包裝腳本,使其不會執行兩次。見下文。爲了堆棧溢出片段,我通過在代碼片段中重複部分視圖兩次來模擬它,以表示在母版頁中包含兩次局部視圖。

我的母版頁可能看起來像:

<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 -->

+1

儘管事實上有更多upvoted的答案,我只是建議這個aproach,而不是分裂高度凝聚力的依賴關係,只是爲了通過擴展對它們進行分組。所以,是我的一個大++。 –

+0

我非常贊同:不要拆分HTML和JS。毫無疑問......但是你的示例局部視圖不適用於ASP MVC的Visual Studios模板的所有消費者:內部'_Layout.cshtml' jQuery在*'@RenderBody()'後面呈現,所以你不能使用它。你的解決方法並不是更好:第一行''將包含jQuery兩次或更多次(每個局部視圖1次,你在'_Layout.cshtml'中1次' ) – Marcel

+0

@Marcel - 該示例旨在在代碼段編輯器中運行,以顯示該技術。我實際上已經警告過,包括多個jQuery包含在我的回答中並提出了改進建議,所以我不確定你是否閱讀了我的「免責聲明」。我真正的佈局頁面通常在頭部有jQuery和其他腳本。額外的工作超出了當時我的答案的範圍/時間要求。只要它仍然在Stack Overflow中運行,歡迎您改進此答案 – codenheim

相關問題