ASP.NET MVC ---模型在視圖中的傳遞


      最近剛學ASP.NET MVC,雖然只是敲了個簡單的例程,但收獲還是有的。

      MVC中最基本的東西就是:Model(模型),View(視圖),Controller(控制器)。對於這三者的關系必須要非常清楚,尤其是在程序的運行中,這三者是怎樣相互配合。簡單來講,控制器決定行為,模型存放數據,視圖顯示行為處理數據后的結果(或者是單純的顯示數據),實際上遠比這個復雜得多。

      控制器由一系列操作組成,這些操作一般都是返回一個ActionResult,而ActionResult包括Json,View等等。先說說View。

      View()方法的使用非常簡單。默認無參的重載版本返回的是與操作同名的視圖,像是下面這樣:

public ShoppingController : Controller{
    public ActionResult Index(){
         return View();
    }
}

      返回的就是/Views/Shopping/Index.cshtml。良好的MVC編程方式就是將相關的東西放在一起,像是將與ShoppingController有關的視圖放在一個單獨的文件夾Shopping就比較方便了。

      但是我們也可以指定該操作顯示的視圖,像是這樣:

return View("Shopping");

      就不是顯示默認的Index.cshtml,而是Shopping.cshtml。

      神奇的是,我們還可以通過View()傳遞模型給相應的視圖。

      像是這樣:

public ActionResult Index(int id){
    return View(id);
}

      就能將模型項System.Int32傳遞給視圖Index.cshtml。神奇吧,int竟然是模型項!這沒有什么好驚訝的,因為在MVC中,所謂的模型就只是一些C#類型,而System.Int32本身就是一個類型,所以,可以被當做模型項處理也是很正常的。
      傳遞模型項的目的當然就是使用該模型項,像是下面這樣:

@model System.Int32

   ...

<h2>@Model</h2>

      我們就可以在視圖中使用該模型項了,但是必須導入該模型,就是通過@(相當於C#的using,java的import)。導入模型必須指定命名空間,Int32的命名空間就是System.Int32,但如果是我們自定義的類型,就必須完整的指定該類型的命名空間。使用的時候,也是使用@(也就是Razor語法),@Model就是使用該模型id的值。當然,如果是自定義的類型,而且是包含有方法的類型,我們可以通過@Model.+ method來調用相關的方法。
      在寫例程的時候,我就發現一個問題,就是會有這樣的錯誤提示:未將對象引用設置為對象實例(NullReference)。這時我們就要細心的檢查,是否有導入相關的模型,操作中有沒有傳參,參進來的模型項是否是null。

      向視圖傳遞模型非常重要,比如說,我們想要在視圖中顯示一個模型的狀態,那么,我們就必須將當前狀態的模型傳遞給視圖,這些都是通過簡簡單單的傳參動作就能搞定。也許,我們可以在視圖中引用該模型。確實,我們可以通過jQuery來通過HttpContext來獲得該模型的相關狀態,像是這樣:

 function handleUpdate()
    {

        //Load and deserialize the returned JSON data
        var json = context.get_data();
        var data = Sys.Serialization.JavaScriptSerializer.deserialize(json);

        //Update the page elements
        if (data.ItemCount == 0) {
            $("#row-" + data.DeleteId).fadeOut("slow");
        }
        else
        {
            $("#item-count-" + data.DeleteId).text(data.ItemCount);
        }

        $("#cart-total").text(data.CartTotal);
        $("#update-message").text(data.Message);
        $("#cart-status").text("Cart(" + data.CartCount + ")");
    }

         相應的視圖部分代碼如:

 @foreach (var item in Model.CartItems)
    {
        <tr id ="row-@item.RecordId">
            <td>
                @Html.ActionLink(item.Album.Title, "Details", "Store", new{ id = item.AlbumId }, null)
            </td>
            <td>
                @item.Album.Price
            </td>
            <td id ="item-count-@item.RecordId">
                @item.Count
            </td>
            <td>
                <a href ="#" class ="RemoveLink" data-id ="@item.RecordId">Remove from cart</a>
            </td>
        </tr>
    }
    <tr>
        <td>
            Total
        </td>
        <td></td>
        <td></td>
        <td id ="cart-total">
            @Model.CartTotal
        </td>
    </tr>

       可以看到,jQuery是通過$來執行的,像是$("#cart-total")就是獲取id為cart-total的HTML元素(好吧,這類似於javascript,但jQuery本來也就是一個javascript的開源庫)。$並不是一個符號,它是一個函數名,就是一個函數的別名,像是這樣:

$(function(){
   ...
});

      它就是參數中匿名函數的別名。當我們傳遞一個匿名函數作為參數的時候,就相當於我們假定該函數是在瀏覽器完成構建HTML的文檔對象模型后立即執行的函數。這樣的假定是有好處的,防止函數中與DOM(Document Object Model,即文檔對象模型)相沖突的腳本,導致DOM無法順利加載。
      如果認為$只是單純的函數別名那就錯了,它的作用遠非如此。像是上面的獲取元素id,就發揮了選擇器的作用,我們還可以進一步指定相關元素中的子元素:

$("#cart-total img")

      這樣就是指定id為cart-total的HTML元素中的img元素。如果是javascript,就需要好幾個函數了。
      $的神奇之處就是,當它作為選擇器的時候,會返回一個包含零個或多個匹配元素的封裝集(wrapped set),我們還可以在該封裝集上繼續調用相關的方法(這些方法必須是依賴於封裝集的方法,當然,它們同樣是返回封裝集)。這就是方法鏈。

     我不知道該原因是否是VS2012的問題,有時候我通過View()傳遞模型項的時候,會出現模型項為空的情況。可怕的是,我的模型傳遞並沒有錯誤,視圖也是該模型的強類型視圖,就算調試也調試不出什么錯誤,結果我就關機重啟,然后所有的問題都消失了!關機重啟並不是解決問題的方式,只是因為那時候我想要睡覺了而已!如果有遇到類似問題的同學,也可以考慮和我一樣:先關機睡一覺,然后再看看情況。

     


     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM