• 【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/
  • 相关阅读:
    jquery绑定点击事件动画BUG
    初步了解XSS攻击
    构造函数、原型对象、原型链之间的关系
    SQA计划和系统测试规程
    第四次scrum冲刺
    第二次Scrum冲刺
    前端面试题整理
    vue 2 简化版数据响应原理
    Vue3.0 简化版数据响应式原理
    git commit规范
  • 原文地址:https://www.cnblogs.com/Wayou/p/AccessViewDatainJavascript.html
Copyright © 2020-2023  润新知