• 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()传递模型项的时候,会出现模型项为空的情况。可怕的是,我的模型传递并没有错误,视图也是该模型的强类型视图,就算调试也调试不出什么错误,结果我就关机重启,然后所有的问题都消失了!关机重启并不是解决问题的方式,只是因为那时候我想要睡觉了而已!如果有遇到类似问题的同学,也可以考虑和我一样:先关机睡一觉,然后再看看情况。

         


         

  • 相关阅读:
    4、linux-grep awk sed and cuf sort uniq join
    2、linux-compress and uncompresse
    1、linux-wget
    Blast 如何使用Blast+(Linux)转载
    1、R-reshape2-cast
    2、R-reshape2-melt
    doc下批处理文件的感想
    关于大数的四则运算
    hadoop分布式安装教程(转)
    关于java中sizeof的问题
  • 原文地址:https://www.cnblogs.com/wenjiang/p/2995676.html
Copyright © 2020-2023  润新知