MVC学习笔记3

许多发展平台减少代码和简化维护,使用模板和 HTML5 和 JavaScript 也不例外。 JsRender 是一个 JavaScript 库使您可以一次定义一个样板文件结构,并使用它来动态地生成 HTML。 JsRender 为具有 codeless 标记语法和高性能,有没有依赖项,对 jQuery 也没有文档对象模型 (DOM)、 支持创建自定义函数并使用纯基于字符串的渲染的 HTML5 开发带来新的模板库。 本专栏讨论的方案的 JsRender 是理想,并演示如何使用它的各种功能。 可以从下载的所有代码示例 archive.msdn.microsoft.com/mag201204ClientInsight,而且可以从都下载 JsRenderbit.ly/ywSoNu

鲍里斯 · 摩尔和 jQuery UI 团队博客,在 2011 年 4 月决定把 jQuery 模板的团队对有利创建逻辑更少、 基于字符串的渲染图书馆举行。 这导致摩尔 (jQuery 模板的幕后推手之一) 创建 JsRender 和 JsViews。 这些两个库是有效的 jQuery 模板更换。 您可以阅读更多关于历史的模板化与 JsRender 已经对有关的 jQuery 的模板和 JsRender 路线图摩尔后 (bit.ly/AdKeDk) 和 jQuery 团队的邮政 (bit.ly/fhnk8A)。 客户端的洞察力将探讨未来几个月的 JsRender 和 JsViews。

为什么模板?

使用模板使用 JavaScript 减少了,简化了代码。 如果不使用模板,添加列表项目和其他 HTML 元素的一组数据的一系列可能需要操纵浏览器的 dom。 这是其中使用插件如 JsRender 的模板可以是相当有用了繁重的任务。 例如,让我们假设您检索一组影片和您要显示它们。 您可以编写 JavaScript 和处理 DOM,但下面的代码演示,甚至这一简单任务可以变得难以阅读,即使使用 jQuery 的帮助:

  1.  
  2.           // Without a template
  3. var i = 1;
  4. $(my.vm.movies).each(function () {
  5.   var movie = this;
  6.   $("#movieContainer1").append(
  7.     "<div>" + i++ + ": " + movie.
  8.           name + " ("
  9.     + movie.releaseYear + ")</div>");
  10. });
  11.         

代码完全写与 JavaScript 和 jQuery,但它可以难分辨从 JavaScript 数据的 HTML。 使用模板,我们可以更容易地单独的结构和消除大部分的 JavaScript 代码。 下面的模板 (附带的代码下载 01-with-and-without-templates-with-jquery.html) 说明这一概念:

  1.  
  2.           <script id="myMovieTemplate" type="text/x-jsrender ">
  3.   <div>{{:#index+1}}: {{:name}} ({{:releaseYear}})</div>
  4. </script>
  5.         

请注意模板包在脚本标记、 其类型相应地设置但已 id,以便它可以稍后标识。 模板渲染需要三个方面:模板、 数据和容器。 模板定义了如何将呈现数据,并在容器定义呈现它的位置。 下面的代码演示如何呈现电影使用名为 myMovieTemplate 的 movieContainer id 的元素的模板的列表:

  1.  
  2.           $("#movieContainer").html($("#myMovieTemplate").render(my.vm.movies));
  3.         

此示例使用 jQuery 简化语法。 值得注意的是 JsRender 并不是依赖于 jQuery。 如下所示 (02-jsrender-无-供代码下载中),还可以写代码以使用 JsRender 呈现使用模板的数据:

  1.  
  2.           my.vm = {
  3.   movies: my.getMovies()
  4. };
  5. jsviews.templates({
  6.   movieTemplate: document.getElementById("myMovieTemplate").innerHTML
  7. });
  8. document.getElementById("movieContainerNojQuery").innerHTML
  9.   = jsviews.render.movieTemplate(my.vm.movies);
  10.         

呈现模板

你可以呈现模板使用 JavaScript 在几个方面。 首先你要作为一个字符串或在 <script> 中定义您的模板 标记。<script> 当您要定义您的模板,在 HTML 中,给他们一个 id 并重用它们好标记选项。 您还可以创建模板从字符串,使你有能力在代码中动态创建它们或将它们甚至拉从数据存储区。

Render 方法用于呈现 HTML 内容从数据使用的模板。 一组数据可以用在 <script> 中声明的模板呈现 标记使用语法 $("# myTmpl").render(data)。 例如,您可以与使用以下代码模板呈现电影的列表:

  1.  
  2.           // #1: Render the my.vm data using the scriptTmpl from a script tag
  3. var htmlString = $("#scriptTmpl").render(my.vm);
  4. // Insert the htmlString into the DOM
  5. $("#div1").html(htmlString);
  6.         

也可以编译中使用 $.templates(tmplString) 函数的字符串的一个模板,并将其设置为一个变量。 然后可以渲染编译后的模板中,如下所示:

  1.  
  2.           // #2: Compile a template from a string, return a compiled template
  3. var tmpl2 = $.templates(tmplString);
  4. htmlString = tmpl2.render(my.vm);
  5. $("#div2").html(htmlString);
  6.         

您还可以编译使用 $.templates (模板名称) 语法中,字符串中的一个模板,如下所示:

  1.  
  2.           // #3: Compile a template, name and register it
  3. $.templates("myTmpl3", tmplString);
  4. var htmlString = $.render.myTmpl3(my.vm);
  5. $("#div3").html(htmlString);
  6.         

在此示例中,$.templates 函数编译使用 tmplString 字符串的模板,并将其注册为命名模板。 然后可以按名称访问该模板,并使用 $.render 呈现。 name() 语法。

$.Templates 功能是类似 jQuery 方法如.css 或.attrib,它提供一个替代的语法用于注册和编译一个调用中的多个模板。 传递两个参数 (名称和 templateString),而不是,您可以传递组成与映射对象的每个模板予以注册键/值对的只是一个参数:

  1.  
  2.           // #4: Compile multiple templates, register them and render
  3. var tmplString2 = "<div>*** {{:movies.length}} Total Movies ***</div>";
  4. $.templates({
  5.   tmpl4a: tmplString,
  6.   tmpl4b: tmplString2
  7. });
  8. htmlString = $.render.tmpl4a(my.vm);
  9. htmlString += $.render.tmpl4b(my.vm);
  10. $("#div4").html(htmlString);
  11.         

在对象中的每个属性都将成为一个命名和注册的模板,可以呈现。 属性的值是字符串,将成为该模板。

有许多选项可以创建、 注册和呈现模板。 在脚本标记中定义模板是一个共同的方法,对于大多数情况。 然而,从字符串创建模板提供了很大的灵活性。 前面扩展后的语法提供了更多的灵活性,将与命名模板 (如 helper 函数声明特定于该模板) 关联的其他功能。 所有这些示例可以在代码下载 03 呈现 templates.html 中找到。

JsRender 基础知识

JsRender 模板包含 HTML 标记,再加上 JsRender 的标签,例如 {{为 … …}} 标记或 {{: … …}} 标记。 图 1 显示为最基本的 JsRender 标记语法:{:} 和 {{> }} 标签。 所有 JsRender 模板标签都封装与双大括号。 标记名称 (在此情况下":"或">"字符) 后面可以由一个或多个参数或表达式。 ({:} 标记中的情况下,表达式的结果将然后呈现。)一旦定义了一个模板和要呈现在该模板中的数据,它可以呈现。

图 1 JsRender 基本语法

Description 示例 Output
没有编码的数据项目的名字属性的值 {{: 名字}} 梅德林
没有编码的嵌套属性的简单对象路径 {{: movie.releaseYear}} 1987
简单的比较 {{: movie.releaseYear < 2000}} True
没有编码的价值 {{: 电影。 }} name 星球大战四:大战之绝地归来
HTML 编码值 {{> 影片。 }} name 星球大战:第六集:< 区域样式 =' 颜色: 紫色 ; 字体样式:斜体 ; ' > 之绝地归来 </span>
HTML 编码值 {{html:movie。 }} name 星球大战:第六集:< 区域样式 =' 颜色: 紫色 ; 字体样式:斜体 ; ' > 之绝地归来 </span>

下面的代码包含 HTML 元素命名为电影­(这是哪里会呈现模板) 的容器:

  1.  
  2.           <div id="movieContainer" class="resultsPanel movieListItemMedium"></div>
  3. <script id="movieTemplate" type="text/x-jsrender">
  4.   <div class="caption">{{:name}}</div>
  5.   <div class="caption">{{>name}}</div>
  6.   <img src="{{:boxArt.smallUrl}}"/>
  7.   <div class="text">Year Released: {{:releaseYear}}</div>
  8.   <div class="text">Rating: {{:rating}}</div>
  9. </script>
  10.         

前面的代码还包含名为影片的模板­模板,它定义要显示的使用没有使用的语法的 HTML 编码的电影名称的 div {{: 名称}}。 标题中的示例数据可能包含 HTML 元素,因此呈现包含 HTML 元素很重要,不能使用的编码。 但是,如果要呈现的已编码的 HTML,您可以使用语法与 > 字符或使用 HTML (如图所示,在图 1)。

Name 属性值包含 HTML 元素,所以仅用于演示目的,前面的代码显示名称属性的值没有编码 ({{: 名称}}) 然后显示 HTML 编码值 ({{> 名称}})。 您可以在代码下载 04 呈现 values.html 运行完整的示例。

传递给该模板的示例影片数据有 boxArt,这反过来为图像的 smallUrl 属性的属性。 Img 标签的 src 由潜水到对象图的层次结构中使用点语法 boxArt.smallUrl 设置。 路径也使用方括号将经历,而不是写的 boxArt.smallUrl,同样会导致代码实现使用 boxArt [smallUrl]。

它是必须注意的 JsRender 语法也可以用于呈现其他值如类或 id 的 HTML 元素的名称。

JsRender 模板渲染检测数据参数是否为数组或不。 如果它是一个数组,返回值是字符串会导致从每个单个数组项传递的 render 方法的串联。 所以一旦每个数据项目和结果将串联的字符串将呈现模板。

下面的代码演示如何呈现数组中的单个影片对象到 (完整源是可用的示例 04-呈现-values.html) 的 movieTemplate:

  1.  
  2.           my.vm = { movies: getMovies() };
  3. $("#movieContainer").html($("#movieTemplate").render(my.vm.movies[1]));
  4.         

下一节将演示如何写入该模板循环访问数组。

钻进分层数据

模板通常用于呈现一系列的项目,它往往可以包含嵌套和分层数据 (对象图表)。  2 JsRender 可以遍历使用 {{}} 的数据系列的显示标记。 该参数为 {{为}} 标记可以是一个数组或一系列的数组,这将迭代。

图 2 迭代基础知识

Description 示例 Output
循环遍历每个项的数组,用"为"

{{为铸造}}

<div> {{: stageName}} </div>

{{/}}

伦敦的爸爸

埃拉爸爸

使用 #data 的数据上下文的访问 {{为电话}} <div> {{: #data}} </div> {{/}}

555-555-1212

555-555-1212

影片中的示例数据定义每个影片有一系列的评级称为 RatingStars 的星星。 该属性包含要显示的电影评级明星的 CSS 类。 (从 05-为-data.html 示例代码中) 下面的代码演示如何循环访问每个 RatingStars 数组中的项和呈现 CSS 类的名称使用 {{: #data}} 语法:

  1.  
  2.           <ul>
  3.   {{for ratingStars}}
  4.   <li class="rating {{:#data}}"/>
  5.   {{/for}}
  6. </ul>
  7.         

#Data 令牌是 JsRender 关键字表示正在迭代的对象。 在此情况下,RatingStars 数组包含一个字符串数组,所以 #data 将代表一个字符串。 此示例输出所示图 3、 评级星星的影片的图像旁边显示的位置。

 
图 3 渲染对象与无编码

阵列模板

当数组传递给模板时,模板被呈现一次的数组中的每个项。 模板渲染对单个数据的项目,但如果它包括 {{}} 模板标签与数组参数,然后在开始和结束标记 {{的}} 模板的部分和 {{/}} 将进一步迭代。 下面的代码会通过对象 my.vm 包含电影来呈现功能,以显示列表项的每个影片 (完整源可以找到在示例 06 如果 else.html) 的数组:

  1.  
  2.           $("#movieList").html($("#movieTemplateMedium").render(my.vm));
  3.         

该模板将呈现为 <ul> 的内容 具有 id movieList 元素:

  1.  
  2.           <ul id="movieList"></ul>
  3.         

图 4 显示模板电影­TemplateMedium 一开始就呈现 <li>。 为每一部电影在数组中,<li> 将呈现在容器的 <ul> 下。

在模板图 4 接收的 my.vm 对象,作为其上下文,然后循环遍历因为电影数组属性 {{为电影}} 代码。 如果该模板收到的 my.vm,而不是数组 my.vm.movies {{为}} {{/}} 块可以被删除,因为该模板,然后将数组中的每个项目的执行。

图 4 呈现项的列表和使用条件语句

  1.  
  2.           {{for movies}}
  3.   <li class="movieListItemMedium">
  4.   <div class="caption">{{:name}}</div>
  5.   {{if boxArt.smallUrl}}
  6.     <img src="{{:boxArt.smallUrl}}"/>
  7.   {{else}}
  8.     <img src="../images/icon-nocover.png"/>
  9.   {{/if}}
  10.   <br/>
  11.   <div class="text">Year Released: {{:releaseYear}}</div>
  12.   <div class="text">rating: {{:rating}}</div>
  13.   <ul>
  14.     {{for ratingStars}}
  15.       <li class="rating {{:#data}}"/>
  16.       {{/for}}
  17.   </ul>
  18.   <br/>
  19.   <div class="text">${{:salePrice}}</div>
  20.   {{if fullPrice !== salePrice}}
  21.     <div class="text highlightText">PRICED TO SELL!</div>
  22.   {{/if}}
  23.   </li>
  24. {{/for}}
  25.         

遍历路径

如我们先前所见,可以使用点语法或方括号来遍历路径。 但是,也可以回去的使用 #parent 对象层次结构或标识使用方括号的数组元素。 例如,您可以替换的 img 标签显示以下与模板中的代码:

  1.  
  2.           <img src="{{:#parent.parent.data[2].boxArt.smallUrl}}"/>
  3.         

该模板的上下文是 my.vm.movies 数组中的项。 所以通过两次通过父导航向上,上下文将成为 my.vm 对象。 然后可以抓取索引 2 的电影,并使用它的 boxArt.smallUrl 属性的图像。 这将会显示同一部电影 (第三电影) 的数组中的每一部电影 (如图所示,在图 5)。 不完全理想在这种情况,但它是显示如何遍历向上和向下在层次结构中这两个对象的点。

 
图 5 遍历每一部电影为显示相同的影片图像路径

条件语句

JsRender 语法也支持条件语句使用标记 {{如果}} 和 {{别的}} (示图 6)。 {{如果}} 标记可能跟着零,一个或多个 {{别的}} 标签,然后关闭 {{和}} 标记。 {{If}} 之间的代码块的内容标记和 {{和}} (或达如果存在的第一个 {{别的}} 标记) 将在输出中呈现,仅当在 {{if}} 表达式的值是"truthy"。

图 6 条件语句、 表达式和运算符

Description 示例 Output
创建一个 if 块比较评估

{{如果 fullPrice! = = salePrice}}

< div 类 ="文本 highlightText">

定价出售! </div>

{{和}}

卖出的价格 !
那么块

{{如果 qtyInStock > = 10}}

股票

{{其他 qtyInStock}}

只有 {{: qtyInStock}} 左 !

{{别的}}

不可用。

{{和}}

只有 5 左 !

{{别的}} 标记可以像这个,当它包括表达。 注意到第二个示例在图 6,其中演示了与两个其他标记的条件。 此代码计算在序列中的三个条件。

继 {{其他 someCondition}} 标记的块将输出,如果条件计算结果为 true (或更确切地说,truthy)。 此语法可用于有效地像开关/案例语句评估 n 多的条件。

JsRender 标签中使用的表达式可以是复杂的表达式使用评价运算符包括路径,字符串、 数字、 函数调用和比较运算符如 = = =,! = = 和 < =。 这是两个表达式进行计算和由 {:} 标记中,并且,在这里,呈现的情况下使用在 {{if}} 和 {{别的}} 的条件表达式标记。

使用计数器和复杂的条件表达式

有时是显示或使用计数器变量的模板中。 一个此类方案时,您要在模板中显示行号。 另一种这种情形可能是您要在模板中的每个元素分配一个唯一的 id,所以你可以参考它以后。 例如,您遍历的电影列表,您包装他们里面所有的 <div> 标记。 您可以指定为 movieDiv1、 movieDiv2 等的 div 标签的 id。 然后,您可以查找元素按其需要时,也许是为了将其绑定到事件处理程序使用 jQuery 的委托函数的 id。 对于这两种情况中,您可以使用 JsRender 关键字: create (该从 0 开始)。 如图所示,在图 7,: create 可以非常轻松地显示在模板中。

图 7 计数器和多个表达式中的条件语句

Description 示例 Output
要计数的模板内使用索引

{{为电影}}

< div 类 ="字幕">

{{:: create}}:{{: 名称}}

</div>

{{/}}

3: 公主新娘
使用逻辑运算符

{{如果 stars.length | cast.length}}

< div 类 ="文本"> 全体演员: </div>

{{和}}

全体演员:

很多时候单个表达式可能不充分。 JsRender 支持多个表达式使用逻辑运算符如 | |和 & & ("和"和"分别)。 这样就容易合并多个表达式,当您想要试用的任何一个是真的。

一起循环访问多个阵列

{{为}} 标签还可以循环访问多个阵列一次。 当有需要遍历一起的两个数组时,这是很有帮助。 例如,下面的代码演示如何为标记将循环访问星星和铸造数组一起:

  1.  
  2.           {{for stars cast}}
  3.   <div class="text">{{:name}}</div>
  4. {{/for}}
  5.         

如果有星星数组中的两个项目和铸造数组中的三个,将呈现所有五项内容。

如果数组中的项目并不是 (具有属性的对象),但简单的字符串值,这是使用过,#data 关键字的良好局面。 例如,数组可以是包袱化和 HomePhones 字符串数组,并可能要在单个列表中将其列出。

嵌套的模板

应用程序经常检索对象凡具有的属性,其值均还可能包含其他对象的数组的对象数组的对象图。 这些方案可以很快变得难以管理嵌套 {{}} 语句的多时。 考虑客户对象可能有命令,其中有秩序的项目,有一种产品都有。 这个层次的数据可以由使用多个 {{为}} 标记呈现。 这是一个很大的情况,内容的 {{为}} 可以作为一个单独的模板打包和作为嵌套模板呈现块。 这可以减少代码和使它更容易地可读和可维护,并提供重复使用和模块化设计的模板。

您可以使用嵌套的模板与 {{为}} 通过删除 (使它自闭) 的块内容标记和指定外部的模板,使用 tmpl 参数。 例如,您可以设置将命名模板 (注册使用 $.templates) 的名称 tmpl 参数或您可以使用一个 jQuery 选择器在脚本块中声明一个模板。 下面的语法使用命名的模板 myTmpl 名为 myArray 的数组中的每个项:

  1.  
  2.           {{for myArray tmpl="myTmpl"/}}
  3.         

下面的代码片断将 movieTemplateMedium id (从示例 04-tmpl-组合-iterators.html) 的电影数组中每个项目使用模板:

  1.  
  2.           <ul>
  3.   {{for movies
  4.     tmpl="#movieTemplateMedium"/}}
  5. </ul>
  6.         

可以循环访问多个阵列,并给他们,以及应用模板。 例如,下面的代码段将使用 castTemplate 的星和铸造中的每项属性 (它们是两个数组从样本 07-tmpl-组合-iterators.html):

  1.  
  2.           <ul>
  3.   {{for stars cast tmpl="#castTemplate"/}}
  4. </ul>
  5.         

请注意,在先前的每个代码片段 {{}} 标签是一个自结束标记,而不是包含内容的块标签。 迭代其块内容,而不是它正在推迟到嵌套模板由 tmpl 属性指示迭代,并渲染那一次每个数组中的项的模板。

{{如果}} 模板标签,也可以用作自结束标记引用另一个模板,其内容,就像 {{为}} 标记。 例如,下面的代码将呈现命名的模板 myAddressTmpl,如果地址是 truthy:

  1.  
  2.           {{if address tmpl="myAddressTmpl"/}}
  3.         

可供下载的示例演示的所有本文中讨论的功能。 图 8 显示的使用所有这些功能从样本 07 呈现的电影列表-tmpl-­组合 iterators.html 文件。

 
图 8 放到一起

下盖更多

此列演示基本特征的 JsRender,但有更多在幕后。 例如,虽然有条件标记可以包含多个 {{为}} 标记 (例如,开关/案例语句) 的条件,可能简洁的方式来处理这种情况,例如,使用自定义标记。 JsRender 支持自定义标记的复杂的逻辑,helper 函数,导航对象图形使用路径,客户转换器功能,允许 JavaScript 代码内模板、 模板的封装和更多。 我将会探讨的一些这些技术在下一个问题。

 

John Papa 曾任 Microsoft Silverlight 和 Windows 8 团队推广专家,他主持的 Silverlight 电视秀节目深受观众欢迎。介绍了全球在要点和会议的生成,混合,PDC、 TechEd,Visual Studio 住 ! 和 DevConnections 事件。爸爸也是微软的区域主任,专栏作家 forVisual Studio 杂志 (爸爸的角度) 的培训视频 Pluralsight 的作者。有关他的情况,请访问 Twitter 上的 twitter.com/john_papa

多亏了以下的技术专家审查这篇文章:Boris Moore

摘自:https://msdn.microsoft.com/zh-cn/magazine/hh882454.aspx

原文地址:https://www.cnblogs.com/chenjiazhu/p/4447341.html