《AngularJS实战》——2.3 Angular中的模板

简介:

本节书摘来自华章出版社《AngularJS实战》一 书中的第2章,第2.3节,作者:陶国荣,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.3 Angular中的模板

Angular自身提供了一整套完整的模板系统,配合$scope对象和数据双向绑定机制,将页面纯静态元素经过行为、属性的添加和格式的转换,最终变成在浏览器中显示的动态页。
在模板系统中,可以包含Angular的指令、数据绑定、表单控件和过滤器,同时,在处理复杂程序时,可以构建多个模板页面作用于视图层。在主页中,再通过包含(include)的方式加载这些零散的模板页。这样做的好处在于,一次定义可多处调用,增加代码的重复使用,减少维护成本。

2.3.1 构建模板内容

构建模板的内容是使用模板功能的前提,一般通过下列几种方式来实现。
直接在页面中添加元素和Angular指令,依赖控制器中构建的属性和方式绑定模板中的元素内容和事件,实现应用需求。
通过“type”类型为“text/ng-template”的

<!doctype html>
<html ng-app="a2_9">
<head>
    <title>构建模板内容</title>
    <script src="../Script/angular.min.js"
            type="text/javascript"></script>
</head>
<body>
    <script type="text/ng-template" id="tplbase">
        姓名:{{ name }},<br />邮箱:{{email}}
    </script>
    <div ng-include src="'tplbase'" ng-controller="c2_9"></div>
    <script type="text/javascript">
        var a2_9 = angular.module('a2_9', []);
        a2_9.controller('c2_9', ['$scope', function ($scope) {
            $scope.name = '陶国荣';
            $scope.email = 'tao_guo_rong@163.com';
        }]);
    </script>
</body>
</html>

(3)页面效果
执行HTML文件2-9.html,最终实现的页面效果如图2-9所示。

dbaa1d122ad87fc3b9be3e11916a3ebfc1984635

(4)源码分析
在本示例的源码中,先添加一个“type”类型为“text/ng-template”的

2.3.2 使用指令复制元素

在构建模板内容的过程中,有时需要反复将不同的数据加载到一个元素中,例如,通过

元素绑定一个数组的各成员。此时,可以使用“ng-repeat”指令,它的功能是根据绑定数组成员的数量,复制页面中被绑定的元素,并在复制过程中添加元素相应的属性和方法,通过这种方式,实现数组数据与元素绑定的过程。
在使用“ng-repeat”指令复制元素的过程中,还提供了几个非常实用的专有变量,可以通过这些变量来处理显示数据时的各种状态。这些变量的功能分别如下。
$f?irst,该变量表示记录是否是首条,如果是则返回true,否则返回false。
$last,该变量表示记录是否是尾条,如果是则返回true,否则返回false。
$middle,该变量表示记录是否是中间条,如果是则返回true,否则返回false。
$index,该变量表示记录的索引号,其对应的值从0开始。
接下来,通过一个示例来演示使用“ng-repeat”指令复制元素的过程。
示例2-10 使用指令复制元素
(1)功能描述
在页面中,通过元素显示一个数组中的全部成员数据,并且在显示数据时列出当条记录是否为“首条”和“尾条”记录的状态信息。
(2)实现代码
新建一个HTML文件2-10.html,加入如代码清单2-10所示的代码。
代码清单2-10 使用指令复制元素
<!doctype html>
<html ng-app="a2_10">
<head>
    <title>使用指令复制元素</title>
    <script src="../Script/angular.min.js"
            type="text/javascript"></script>
    <style type="text/css">
        body {
            font-size: 12px;
        }
        ul {
            list-style-type: none;
            width:400px;
            margin: 0px;
            padding: 0px
        }
            ul li {
                f?loat: left;
                padding: 5px 0px;
            }
                ul li span {
                    width: 50px;
                    f?loat: left;
                    padding: 0px 10px;
                }
    </style>
</head>
<body>
    <div ng-controller="c2_10">
        <ul>
            <li>
                <span>序号</span>
                <span>姓名</span>
                <span>性别</span>
                <span>是否首条</span>
                <span>是否尾条</span>
            </li>
            <li ng-repeat=" stu in data">
                <span>{{$index+1}}</span>
                <span>{{stu.name}}</span>
                <span>{{stu.sex}}</span>
                <span>{{$f?irst?'是':'否'}}</span>
                <span>{{$last?'是':'否'}}</span>
            </li>
        </ul>
    </div>
    <script type="text/javascript">
        var a2_10 = angular.module('a2_10', []);
        a2_10.controller('c2_10', ['$scope', function ($scope) {
            $scope.data = [
            { name: "张明明", sex: "女" },
            { name: "李清思", sex: "女" },
            { name: "刘小华", sex: "男"},
            { name: "陈忠忠", sex: "男" }
            ];
        }]);
    </script>
</body>
</html>

(3)页面效果
执行HTML文件2-10.html,最终实现的页面效果如图2-10所示。

dfc8df966ac4574c29c78af02afb85859f33b2fd

(4)源码分析
在本示例的源码中,首先,在对应页面的控制器代码中,以$scope属性的方式添加了一个名为“data”的数组,用作页面中

元素绑定的数据源;然后,在页面中添加
  • 元素,并在该元素中再添加两个
  • 元素,第一个用于标题显示,第二个用于绑定“data”数组内容。
    在用于绑定“data”数组内容的第二个
  • 元素中,调用Angular中的“ng-repeat”指令完成数据与页面元素的绑定。在绑定过程中,Angular先遍历“data”数组,在遍历时复制一份
  • 元素,并通过“stu”对象将控制器中的属性和方法添加至该元素中,在遍历完成后便生成了与数组成员数量对应的
  • 元素,并且在这些元素中也添加了需要显示的内容和方法,从而最终实现以列表方式显示集合数据的功能。
    在通过“ng-repeat”指令复制元素过程中,可以通过表达式的方式直接调用Angular提供的几个专用的变量$f?irst、$middle、$last和$index。由于这些变量均返回布尔值,因此,可以根据返回的布尔值,再借助“?:”运算符转成中文显示的文字内容,实现的过程如本示例中的源码所示。

    2.3.3 添加元素样式

    在Angular中,添加元素的样式也非常简单,概括起来可以通过下列几种方式来进行。
    (1)直接绑定值为CSS类别名称的$scope对象属性
    这种方式的操作非常简单,先在控制器中添加一个值为CSS类别名称的属性,然后在页面元素的class或ng-class属性值中,通过双花括号方式绑定属性名即可,如以下代码。

    $scope.red="red";

    上述代码表示在控制器中添加了一个名为“red”的属性,它的属性值是名为“red”的CSS类别名。在添加完“red”属性后,在页面中可以通过下列代码进行调用。

    <div ng-class="{{red}}"></div>

    等价于下列代码:

    <div class="{{red}}"></div>

    这种方式操作起来虽然简单,但在控制器中定义CSS类别名称,并不是Angular所提倡的,我们在开发Angular应用时,尽量保证控制器的代码都是处理业务逻辑,并不涉及页面元素。
    (2)以字符串数组方式选择性添加CSS类别名称
    这种方式将根据控制器中一个布尔类型的属性值来决定页面中元素添加的CSS样式名,当该属性值为true时,添加一个CSS样式名,当属性值为false值时,添加另外一个CSS样式名。下列代码添加一个名为“blnfocus”属性,由它决定页面中

    元素的样式。
    $scope.blnfocus=true;

    接下来在页面的

    元素中添加ng-class属性,并在属性值中通过字符串数组方式来添加CSS类别名称,代码如下。
    <div ng-class="{true:'red',false:’green’}[blnfocus]"></div>

    在上述代码中,

    的CSS样式取决于“blnfocus”属性值,当该值为true时,添加“red”样式名,当该值为false时,添加“green”样式名。这种方式只能在两种样式中选择一种,并且{}和[]顺序不可颠倒。在{}中设置可选择的两种样式名称,在[]中放置控制样式的属性名。
    (3)通过定义key/value对象的方式来添加多个CSS类别名称
    与前面介绍的两种添加CSS类别名的方法相比,第三种方法的功能要强大很多,它可以根据控制显示样式的属性值添加多个样式名。例如,先添加两个用于控制样式显示的“a”和“b”属性,这两个属性的类型均为布尔型,代码如下。
    $scope.a=false;
    $scope.b=true;

    接下来在页面的

    元素中,添加ng-class属性。在设置属性值时,通过定义key/value对象的方式来添加多个CSS样式名,代码如下。
    <div ng-class="{'red':a ,'green':b}"></div>

    在上述ng-class属性值设置过程中,样式名“red”和“green”分别为“key”值,属性值“a”和“b”分别为对应的“value”值。当“value”属性值为true时,则添加对应的“key”即CSS样式名。因此,这种方式可以实现添加多种CSS样式名称,适合在处理复杂样式时使用。
    此外,在Angular中,还有另外两个用于添加样式的页面指令,分别为“ng-class-odd”和“ng-class-even”,这两个样式指令是专用于以列表方式显示数据,对应奇数行与偶数行的样式。
    接下来,通过一个完整的示例来详细介绍样式在页面中的使用。
    示例2-11 添加元素样式
    (1)功能描述
    在示例2-10的基础之上,在样式方面增加3个功能。首先,将第一个

  • 元素中显示的字体加粗;其次,添加“ng-class-odd”和“ng-class-even”两个指令,实现列表的隔行变色的功能;最后,当单击某行
  • 的元素时,显示相应的背景色。
    (2)实现代码
    新建一个HTML文件2-11.html,加入如代码清单2-11所示的代码。
    代码清单2-11 添加元素样式
    <!doctype html>
    <html ng-app="a2_11">
    <head>
        <title>添加元素样式</title>
        <script src="../Script/angular.min.js"
                type="text/javascript"></script>
        <style type="text/css">
            body {
                font-size: 12px;
            }
            ul {
                list-style-type: none;
                width: 408px;
                margin: 0px;
                padding: 0px
            }
                ul li {
                    f?loat: left;
                    padding: 5px 0px;
                }
                ul .odd {
                    color:#0026ff;
                }
                ul .even {
                    color:#ff0000;
                }
                ul .bold{
                    font-weight:bold;
                }
                ul li span {
                    width: 52px;
                    f?loat: left;
                    padding: 0px 10px;
                }
                ul .focus {
                    background-color:#cccccc;
                }
        </style>
    </head>
    <body>
        <div ng-controller="c2_11">
            <ul>
                <li ng-class="{{bold}}">
                    <span>序号</span>
                    <span>姓名</span>
                    <span>性别</span>
                    <span>是否首条</span>
                    <span>是否尾条</span>
                </li>
                <li ng-class-odd="'odd'" 
                    ng-class-even="'even'" 
                    ng-repeat=" stu in data"
                    ng-click='li_click($index)' 
                    ng-class='{focus: $index==focus}'>
                    <span>{{$index+1}}</span>
                    <span>{{stu.name}}</span>
                    <span>{{stu.sex}}</span>
                    <span>{{$f?irst?'是':'否'}}</span>
                    <span>{{$last?'是':'否'}}</span>
                </li>
            </ul>
        </div>
        <script type="text/javascript">
            var a2_11 = angular.module('a2_11', []);
            a2_11.controller('c2_11', ['$scope', function ($scope) {
                $scope.bold = "bold";
                $scope.li_click = function (i) {
                    $scope.focus = i;
                };
                $scope.data = [
                { name: "张明明", sex: "女" },
                { name: "李清思", sex: "女" },
                { name: "刘小华", sex: "男" },
                { name: "陈忠忠", sex: "男" }
                ];
            }]);
        </script>
    </body>
    </html>

    (3)页面效果
    执行HTML文件2-11.html,最终实现的页面效果如图2-11所示。

    cb0d7c0ba663b088f4e031da3c69e57e22b117c4

    (4)源码分析
    在本示例的源代码中,首次定义了名称为“odd”、“even”、“bold”和“focus”的4个样式,分别用于隔行时的两种字体色、标题栏字体变粗和单击某行时的背景色。
    其次,在示例的控制器代码中,除添加“data”数组集合外,再添加了一个“bold”属性,用于指定加粗显示字体时的样式名。另外,还添加了一个带参数的“li_click”方法,当调用该方法时,将“focus”属性值设为传入参数值。
    再有,在示例的页面代码中,先通过双花括号方式将第一个

  • 元素的“ng-class”值与“bold”属性值绑定,由于该值指定的是一个加粗时的样式名,因此,在绑定后,
  • 元素中的字体变粗;然后,使用“ng-class-odd”和“ng-class-even”样式指令分别绑定奇数和偶数行的样式名,实现隔行换色的功能;最后,在
  • 元素的单击事件中,将执行$scope对象中添加的“li_click()”方法,在该方法中将“$index”(行号值)作为实参传给方法,并且将“focus”属性值设置为“$index”值。因此,当单击某行
  • 元素时,“focus”属性值将变为相应的“$index”值。
    最后,在示例页面
  • 元素的“ng-class”样式指令值中通过key/value对象的方式指定该元素需要添加的样式。由于单击
  • 元素时,“$index”变量值和“focus”属性值相同,也就是说,表达式“$index==focus”的返回值为true。因此,“ng-class”样式指令值变为“focus”,最终实现当单击
  • 元素时,添加背景样式的页面效果。

    2.3.4 控制元素的隐藏与显示状态

    在Angular中,可以通过“ng-show”“ng-hide”和“ng-switch”指令来控制元素隐藏与显示的状态,前两个指令直接控制元素的显示和隐藏状态,当“ng-show”值为true或“ng-hide”值为false时,元素显示,反之,元素隐藏。
    后一个“ng-switch”指令的功能是显示匹配成功的元素,该指令需要结合“ng-switch-when”和“ng-switch-defalut”指令使用。在“ng-switch”指令中,当指定的“on”值与某个或多个添加“ng-switch-when”指令的元素匹配时,这些元素显示,其他未匹配的元素则隐藏。如果没有找到与“on”值相匹配的元素时,则显示添加了“ng-switch-defalut”指令的元素。
    接下来,通过一个示例来演示控制元素隐藏或显示状态的过程。
    示例2-12 控制元素的隐藏与显示状态
    (1)功能描述
    在页面中,调用“ng-show”“ng-hide”和“ng-switch”指令绑定$scope对象的属性值,控制

  • 元素显示或隐藏的状态。
    (2)实现代码
    新建一个HTML文件2-12.html,加入如代码清单2-12所示的代码。
    代码清单2-12 控制元素的隐藏与显示状态
    <!doctype html>
    <html ng-app="a2_12">
    <head>
        <title>控制元素显示和隐藏的状态</title>
        <script src="../Script/angular.min.js"
                type="text/javascript"></script>
        <style type="text/css">
            body {
                font-size: 12px;
            }
            ul {
                list-style-type: none;
                margin: 0px;
                padding: 0px
            }
            div {
                margin: 8px 0px;
            }
        </style>
    </head>
    <body>
        <div ng-controller="c2_12">
            <div ng-show={{isShow}}>陶国荣</div>
            <div ng-hide={{isHide}}>tao_guo_rong@163.com</div>
            <ul ng-switch on={{switch}}>
                <li ng-switch-when="1">陶国荣</li>
                <li ng-switch-when="2">tao_guo_rong@163.com</li>
                <li ng-switch-default>更多...</li>
            </ul>
        </div>
        <script type="text/javascript">
            var a2_12 = angular.module('a2_12', []);
            a2_12.controller('c2_12', ['$scope', function ($scope) {
                $scope.isShow = true;
                $scope.isHide = false;
                $scope.switch = 3;
            }]);
        </script>
    </body>
    </html>

    (3)页面效果
    执行HTML文件2-12.html,最终实现的页面效果如图2-12所示。

    9dada575901ab31114eac330ad112a4e592da04a

    (4)源码分析
    在本示例的源代码中,前两个

    元素分别添加了“ng-show”和“ng-hide”,并通过双花括号绑定了“isShow”属性和“isHide”属性,这两个属性在控制器中添加时的值分别为true和false,因此,这两个
    元素都将显示在页面中。
    此外,在添加“ng-switch”指令的
    • 元素中,由于“on”值绑定了“switch”属性,而该属性在控制器中添加时的值为3,并且在页面中添加了“ng-switch-when”指令的
    • 元素中,没有找到“ng-switch-when”指令值为3的元素,因此,只能显示添加了“ng-switch-default”指令的
    • 元素,即最后一行显示内容为“更多…”的
    • 元素,最终显示效果如图2-12所示。
相关文章
|
4月前
|
前端开发 开发者 开发框架
JSF与Bootstrap,打造梦幻响应式网页!让你的应用跨设备,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,响应式设计至关重要,以确保不同设备上的良好用户体验。本文探讨了JSF(JavaServer Faces)与Bootstrap框架的结合使用,展示了如何构建响应式网页。JSF是一个基于Java的Web应用框架,提供丰富的UI组件和表单处理功能;而Bootstrap则是一个基于HTML、CSS和JavaScript的前端框架,专注于实现响应式设计。通过结合两者的优势,开发者能够更便捷地创建自适应布局,提升Web应用体验。然而,这种组合也有其局限性,如JSF组件库较小和较高的学习成本等,因此在选择开发框架时需综合考虑具体需求和应用场景。
54 0
|
4月前
|
开发者 Java Spring
JSF 牵手社交登录,如魔法风暴席卷 Web 世界,开启震撼便捷登录之旅!
【8月更文挑战第31天】在互联网时代,便捷登录成为用户的核心需求。社交登录凭借其便捷性、安全性和社交化的特点,在各类Web应用中广泛应用。JavaServer Faces(JSF),作为一款流行的Java Web框架,能够轻松集成社交登录功能,显著提升用户体验。本文详细介绍社交登录的优势,并提供两种JSF集成社交登录的常见方法:一是利用Spring Social等第三方库简化开发;二是自行实现社交登录流程。开发者可根据项目需求选择适合的方案。
47 0
|
4月前
|
开发者 前端开发 开发框架
JSF与移动应用,开启全新交互体验!让你的Web应用轻松征服移动设备,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,移动设备的普及使得构建移动友好的应用变得至关重要。尽管JSF(JavaServer Faces)主要用于Web应用开发,但结合Bootstrap等前端框架,也能实现优秀的移动交互体验。本文探讨如何在JSF应用中实现移动友好性,并通过示例代码展示具体实现方法。使用Bootstrap的响应式布局和组件可以确保JSF页面在移动设备上自适应,并提供友好的表单输入和提交体验。尽管JSF存在组件库较小和学习成本较高等局限性,但合理利用其特性仍能显著提升用户体验。通过不断学习和实践,开发者可以更好地掌握JSF应用的移动友好性,为Web应用开发贡献力量。
53 0
|
4月前
|
开发者 容器 Docker
JSF与Docker,引领容器化浪潮!让你的Web应用如虎添翼,轻松应对高并发!
【8月更文挑战第31天】在现代Web应用开发中,JSF框架因其实用性和灵活性被广泛应用。随着云计算及微服务架构的兴起,容器化技术变得日益重要,Docker作为该领域的佼佼者,为JSF应用提供了便捷的部署和管理方案。本文通过基础概念讲解及示例代码展示了如何利用Docker容器化JSF应用,帮助开发者实现高效、便携的应用部署。同时也提醒开发者注意JSF与Docker结合使用时可能遇到的限制,并根据实际情况做出合理选择。
43 0
|
5月前
|
前端开发 JavaScript
前端框架与库 - Angular基础:组件、模板、服务
【7月更文挑战第16天】Angular,谷歌维护的前端框架,专注构建动态Web应用。组件是核心,包含行为逻辑的类、定义视图的模板和样式。模板语法含插值、属性和事件绑定。服务提供业务逻辑,依赖注入实现共享。常见问题涉及组件通信、性能和服务注入。优化通信、性能并正确管理服务范围,能提升应用效率和质量。学习组件、模板和服务基础,打造高效Angular应用。
69 1
|
前端开发 测试技术 C++
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(进阶篇)
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(进阶篇)
336 0
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(进阶篇)
|
前端开发 JavaScript
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(入门篇)
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(入门篇)
464 0
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(入门篇)
|
前端开发 JavaScript
对于Angular表达式以及重要指令的研究心得【前端实战Angular框架】
对于Angular表达式以及重要指令的研究心得【前端实战Angular框架】
对于Angular表达式以及重要指令的研究心得【前端实战Angular框架】
|
API
Angular 2.x折腾记 :(7) 初步了解表单:模板驱动及数据驱动及脱坑要点
表单在整个系统中的作用相当重要,这里主要扯下响应表单的实现方式。 首先需要操作表单的模块引入这两个模块; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
172 0
Angular模板简介
模板引擎是Web应用中用来生成动态HTML的一个途径, 负责将数据模型与HTML模板结合起来(即模板渲染),生成最终的HTML。 编写HTML模板的语法称为模板语法,模板语法的表达能力和可扩展性决定了模板引擎的易用性。本文将介绍在重构管理控制台中使用到的Angular的模板引擎ng-template。
189 0