zoukankan      html  css  js  c++  java
  • 【MVC】JavaScript代码中获取视图模型的数据

    懂点MVC的人都知道MVC 的机制是访问Contoller下的Action,由Action组织好页面需要的数据然后返回视图(return View()/return PartialView())或数据(return Content(“blah”)/ return Json(…)),有的时候返回视图的同时连带返回数据以供页面使用(return View(model))。

    其实Controller与View之间的传值有很多形式啦,除了传统的Retrun语句向页面返回数据,还可以通过 ViewData,ViewBag等。它们的使用在Razor句法与非Razor句法中稍有不同。

    比如妳新建一个MVC程序,在初始的Home/Index Action里而,就有如下代码:

    public ActionResult Index()
    
            {
    
                ViewBag.Message = "Welcome to ASP.NET MVC!";
    
     
    
                return View();
    
            }


    其中通过ViewBag向页面传送一句文本。那么在页面,我们通过直接书写相同的系统变量名称来访问:

    <h2><%: ViewBag.Message %></h2>


     
     

    再看看ViewData,比如我把刚才通过ViewBag传送的值通过ViewData来完成。

    所以在Home/Index 这个Action里而,修改代码如下:

     
    
    public ActionResult Index()
    
            {
    
                //ViewBag.Message = "Welcome to ASP.NET MVC!";
    
                ViewData["Message"] = "Welcome to ASP.NET MVC!!";
    
     
    
                return View();
    
            }

    它是以数组的形式,随便取了个游标名以便访问数据,这里定义了一个名为“Message”的文本保存到了ViewData里而。

    然后在页面,同样使用相同的语句来访问:

      

    <h2><%: ViewData ["Message"] %></h2>

     

    如果想传递多个变量,直接书写另一个变量就行,然后在页面访问变量名获取数据。

    有意思的是,貌似ViewBag和ViewData 其实是同种东西的不同表示,比如我们定义:

    public ActionResult Index()
    
            {
    
                ViewBag.Message = "ViewBag.Message";
    
                return View();
    
            }


    在页面,既可以通过ViewBag的句法来访问,也可以通过ViewData的句法来访问。反之亦可。
     

     

    <h2><%: ViewData ["Message"] %></h2>
    
    <h2><%: ViewBag.Message %></h2>

      

    但其实上面这些都不是本文我想说的,下面进入主题,如果在JavaScript代码中访问这些数据,进一步说,如何访问由Action 传到页面的数据。

    在由<Script>包围的脚本代码中,自然想到用相同的语法来访问。我们用ViewData进行传递:

    public ActionResult Index()
    
            {
    
               ViewData["message"] = "Data from server.";
    
                return View();
    
            }


    然后在JS代码中,看起来应该是这样子的:
     

    <script >
    
            $(function() {
    
                var data =  <%:ViewData["message"] %>;
    
            })
    
        </script>


    然后一运行发现报错,
     

    但神奇的是我们已经完成任务了。但其实仔细看是不正确的,因为等号后面的语句,不是正常的JavaScript语句。

    那为了避免报错同时使代码正常,我们需要用引号将它包起来,所以看起来应该是这样子的:

     

    var data = ' <%:ViewData["message"] %>';

      

    对于这样的简单数据,似乎就已经够了。但一般Action返回的都是模型(Model)等复杂类型的数据。

    首先,为了说明方便,到Model文件夹下创建一个类文件,叫PersonalModel,为了简单,其内容大概是这样的:

    public class PersonModel
    
        {
    
            public string Name { get; set; }
    
            public int Age { get; set; }
    
        }


    很简单的对象,只包含一个字符串类型的Name属性和一个整型类型的Age属性。
     

    下面再写一个方法产生一些静数据,真实情况下这些数据可能是从数据库取的。为了调用方便这个方法我写在了HomeController 类里面,其样子看起来似乎是这样子的:

    static List<PersonModel> DummyData()
    
            {
    
                var data = new List<PersonModel>()
    
                               {
    
                                   new PersonModel()
    
                                       {
    
                                           Name = "Tom",
    
                                           Age = 20
    
                                       },
    
                                   new PersonModel()
    
                                       {
    
                                           Name = "Cat",
    
                                           Age = 5
    
                                       }
    
                               };
    
                return data;
    
            }


    然后我们去修改Index Action,让它返回数据。
     

    public ActionResult Index()
    
            {
    
                var data=DummyData();
    
                return View(data);
    
            }


    最后我们再去页面的JS代码段里,接收它。
     

    <script >
    
            $(function() {
    
                var model = <%= new JavaScriptSerializer().Serialize(Model) %>;
    
                debugger;
    
            }) 
    
        </script>


    加了个debugger是为了呆会在浏览器里进入调试模式查看数据的方便。
     

    然后我们再到浏览器查看是否得到了数据(记得浏览器是调试模式,按F12进入)。

     

    我们成功在JS代码片段里获得了传来的数据并序例化成了Json格式。

    然后可以通过类似下面的语句来调用。

     

    <script >
    
            $(function() {
    
                var model = <%= new JavaScriptSerializer().Serialize(Model) %>;
    
                alert(model[0].Name);
    
                debugger;
    
            }) 
    
        </script>
    
     

      

     

    上面说的只是在JS里访问,其实这倒不是主要的需求了,只是我们习惯了在页面的使用方法而突然要在JS里访问这些数据时不知道怎么办。

    那在页面里,如何对这种集合类型的数据进行访问。我们都知道向页面传送一个Model时的情形。

    比如下面我们修改Index Action让它只返回一条数据。类型当然为PersonModle了。

    public ActionResult Index()
    
            {
    
                //var data=DummyData();
    
                var data = new PersonModel()
    
                               {
    
                                   Name = "Tom",
    
                                   Age = 20
    
                               };
    
                return View(data);
    
            }


    注意之前的data(注释掉的那个)的类型是List<PersonModel>,它是个集合类型,而现在是PersonModle类型的。理解这点对我们在页面如何正确获取数据非常重要。
     

    然后再去把页面修改为强类型的,经便接收数据(如妳所见,上面我们在JS中想要获得数据时,不需要页面是强类型的)。

    之前的页面类型看起来是这个样子的:

     
    
    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

    现在我们要将它修改为这个样子的:

    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcApplication17.Models.PersonModel>" %>


    然后我们就可以在页面使用传递来的数据了,用类似这样的语法:
     

     

    <p>
    
       Name:<%= Html.DisplayFor(model=>model.Name) %>
    
       Age:<%= Html.DisplayFor(model=>model.Age) %>
    
    </p>

      

    当传递来的是集合类型的数据时,就无法这样简单的访问了,需要遍历集合,取到里面的单条数据后才可使用。

    下面我们就来看一下集合类型时的情境。

    修改Index Action返回的数据为原来的那个:

    public ActionResult Index()
    
            {
    
                var data=DummyData();
    
                return View(data);
    
            }


    然后再去把页面的接收类型相应修改成这个样子的:
     

    <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<MvcApplication17.Models.PersonModel>>" %>


    最后在页面,我们需要遍历这个集合来取得数据,可以用类似这样的句法:
     

     

    <% foreach(var item in Model) { %>
    
            <p>
    
                 Name:<%= Html.DisplayFor(n=>item.Name) %>
    
                 Age:<%= Html.DisplayFor(n=>item.Age) %>
    
            </p>
    
        <% } %>

      

    这里还只是简单谈到了MVC中数据由服务器端到页面的传递,其实更难的是将数据传回服务器绑定到模型。当然,如果妳用表单,直接一个Submit,所有的事情框架都为妳做了,模型很容易就绑定好了。但如果妳的页面有个多模型呢,妳不想用Submit而想自己写Ajax的回传呢,这样的数据传递如何在服务器端获取。。。有时间再谈了。

    可以参考的文章:

    1. ASP.NET MVC using ViewData in javascript(StackOverFlow)
    2. Using ASP.NET MVC v2 EditorFor and DisplayFor with IEnumerable<T> Generic types
    3. http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
    4. http://code-inside.de/blog-in/2012/09/17/modelbinding-with-complex-objects-in-asp-net-mvc/
  • 相关阅读:
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    PTA —— 基础编程题目集 —— 函数题 —— 61 简单输出整数 (10 分)
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    练习2.13 不用库函数,写一个高效计算ln N的C函数
    迷宫问题 POJ 3984
    UVA 820 Internet Bandwidth (因特网带宽)(最大流)
    UVA 1001 Say Cheese(奶酪里的老鼠)(flod)
    UVA 11105 Semiprime Hnumbers(H半素数)
    UVA 557 Burger(汉堡)(dp+概率)
  • 原文地址:https://www.cnblogs.com/Wayou/p/AccessViewDatainJavascript.html
Copyright © 2011-2022 走看看