《AngularJS实战》——2.2 Angular中的控制器

简介:

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

2.2 Angular中的控制器

在介绍完Angular中的表达式后,接下来再来介绍一下Angular中一个重要角色——控制器(controller)。其实,在前面的章节中我们也多次提到它,那么,Angular中的控制器到底是什么?它又能实现哪些功能呢?接下来,我们结合示例来逐一进行解析。

2.2.1 控制器的概念

控制器在Angular中占有重要的地位,它是组成前端MVC框架的一员。在Angular中,控制器的功能是管理页面的逻辑代码。当控制器通过“ng-controller”指令被添加到DOM页面时,Angular将会通过控制器构造函数生成一个实体的对象,而在生成这个对象的过程中,$scope对象作为参数注入其中,并允许用户访问$scope对象。这样一来,用户可以通过$scope对象与页面中的元素进行数据绑定,从而实现数据从控制器层到视图层的过程。

2.2.2 控制器初始化$scope对象

从上面对控制器的介绍,我们不难看出,控制器的任务就是操作$scope对象,而这种操作具体表现在两个方面:一是对$scope对象进行初始化,二是为$scope对象添加各种实现逻辑功能的方法。我们先来看第一个功能,初始化$scope对象。
先通过一个完整的示例来介绍控制器初始化$scope对象的过程。
示例2-4 控制器初始化$scope对象
(1)功能描述
在页面中,以应用模块的方法构建一个控制器对象,并以内联声明方式表明控制器对象依赖于$scope对象提供的服务。在控制器对象中,初始化$scope对象的名为“text”的属性,并与页面的元素进行数据绑定。
(2)实现代码
新建一个HTML文件2-4.html,加入如代码清单2-4所示的代码。
代码清单2-4 控制器初始化$scope对象

<!doctype html>
<html ng-app="a2_4">
<head>
    <title>控制器初始化$scope对象</title>
    <script src="../Script/angular.min.js" 
            type="text/javascript"></script>
</head>
<body>
    <div ng-controller="c2_4">
        <span>{{text}}</span> 
    </div>
    <script type="text/javascript">
        var a2_4 = angular.module('a2_4', []);
        a2_4.controller('c2_4', ['$scope', function ($scope) {
            $scope.text = 'Hello!Angular';
        }]);
    </script>
</body>
</html>

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

545157ab69192437bbc7ea2f38457071dbfe697e

(4)源码分析
在本示例的源码中,自定义控制器函数的创建由全局方式改为在Angular模块下使用. controller方式,这种方式更加强调页面是一个整体的应用,控制器可以对应用中的某一个模块进行管理。相对于全局方式下的定义,该方式的扩展性和针对性更强。
在本示例中,首先定义了一个名为“a2_4”的Angular模块,然后,通过下列代码,创建了一个名为“c2_4”的控制器。

a2_4.controller('c2_4', ['$scope', function ($scope) {
            ...代码块
}]);

在上述的代码中,采用内联注入的方式声明“c2_4”控制器的构建依赖Angular中的$scope对象,即在构建控制器时,Angular会自动将$scope对象作为参数注入到控制器中。
在构建控制器函数时,虽然$scope对象已经自动注入,但还是需要对它进行初始化。初始化的方法是向该对象添加属性,在本示例中的代码如下。
$scope.text = 'Hello!Angular';
采用上述方式也可以添加多个属性,被添加的这些属性在控制器所管理的所有DOM元素中都可以采用数据绑定的方式进行访问。例如, 对于下列代码:

<div ng-controller="c2_4">
        <span>{{text}}</span> 
</div>

通过元素的“ng-controller”属性值指定控制器函数的名称,表明该元素中的全部DOM节点都受控制器管理,然后,采用双花括号的方式绑定控制器的数据,从而最终实现View层数据展示的功能。

2.2.3 添加$scope对象方法

除了可以通过初始化的方式为$scope对象添加属性之外,还可以为$scope对象添加方法,并依靠这些定义的方法来满足视图层中逻辑处理和事件执行的需要。在添加完$scope对象的方法函数之后,在视图层中,就可以像绑定属性一样,通过表达式的方式绑定这些函数,处理业务逻辑需求,也可以通过Angular的事件处理器,将执行的事件(如ng-click)绑定给这些函数,用来实现事件触发时需要完成的功能需求。
接下来,我们分别通过两个示例来介绍添加并执行$scope对象方法的过程。
示例2-5 通过表达式绑定$scope对象的方法
(1)功能描述
在示例2-4的基础上向$scope对象添加一个名为“span_show”的方法函数。在该函数中,先重置$scope对象的“text”属性值,并通过return方法返回重置后的内容值;在页面中,通过Angular表达式绑定$scope对象中的“span_show”函数,显示重置后返回的内容。
(2)实现代码
新建一个HTML文件2-5.html,加入如代码清单2-5所示的代码。
代码清单2-5 控制器初始化$scope对象

<!doctype html>
<html ng-app="a2_5">
<head>
    <title>通过表达式绑定$scope对象的方法</title>
    <script src="../Script/angular.min.js" 
            type="text/javascript"></script>
</head>
<body>
    <div ng-controller="c2_5">
        <span class="show">{{span_show()}}</span>
    </div>
    <script type="text/javascript">
        var a2_5 = angular.module('a2_5', []);
        a2_5.controller('c2_5', ['$scope', function ($scope) {
            $scope.text = 'Hello!Angular';
            $scope.span_show = function () {
                $scope.text = "欢迎来到 Angular 的精彩世界!";
                return $scope.text;
            };
        }]);
    </script>
</body>
</html>

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

c7c63511095714a8d75353e1db924fed3d99a5b2

(4)源码分析
在本示例的源码中,在构建名为“c2_5”的控制器时,除添加“text”属性外,还向$scope对象添加了一个名为“span_show”的方法。该方法是一个自定义的函数,在函数中先重新设置了$scope对象的“text”属性值,再通过return语句返回重置后的属性值。
为了能在页面中执行在控制器中定义的“span_show”方法,在双花括号中以表达式的方式直接调用方法名称,因为调用该方法将返回重置后的$scope对象的“text”属性值,所以,在页面的元素中,显示$scope对象被重置后的字符内容,完整效果如图2-5所示。
除了在页面中,通过Angular的表达式调用$scope对象的方法外,还可以通过Angular的事件处理器将方法与某个事件绑定,在触发事件时执行已绑定的方法。
示例2-6 在事件中绑定$scope对象的方法
(1)功能描述
在示例2-4的基础上向$scope对象添加一个名为“click_show”的方法,同时,在页面中添加一个<button>元素,并在元素的click事件中绑定该方法。当单击按钮时,在页面的<span>元素中显示“单击后显示的内容!”字样。
(2)实现代码
新建一个HTML文件2-6.html,加入如代码清单2-6所示的代码。
代码清单2-6 在事件中绑定$scope对象的方法

<!doctype html>
<html ng-app="a2_6">
<head>
    <title>在事件中绑定$scope对象的方法</title>
    <script src="../Script/angular.min.js" 
            type="text/javascript"></script>
</head>
<body>
    <div ng-controller="c2_6">
        <span class="show">{{text}}</span>
        <input id="btnShow" type="button" 
               ng-click="click_show();" value="显示" />
    </div>
    <script type="text/javascript">
        var a2_6 = angular.module('a2_6', []);
        a2_6.controller('c2_6', ['$scope', function ($scope) {
            $scope.text = 'Hello!Angular';
            $scope.click_show = function () {
                $scope.text = "单击后显示的内容!";
            };
        }]);
    </script>
</body>
</html>

(3)页面效果
执行HTML文件2-6.html,最终实现的页面效果如图2-6所示。
(4)源码分析
在本示例的源码中,在构建控制器时,向$scope对象添加了一个名为“click_show”的方法。在该方法中,将$scope对象的“text”属性重新赋值;在页面中,将“click_show”方法与<button>元素的click事件通过Angular中的事件处理器“ng-click”相绑定,这样在单击<button>按钮时触发click事件,并调用已绑定的“click_show”方法,重置$scope对象的“text”属性值。

546f82e5c0521bd16fd5a2ea67e883db140ddd3f

由于在<span>元素中通过双花括号与“text”属性值进行了双向绑定,因此,一旦重置“text”属性值完成,被绑定的页面内容也将自动进行同步变更,最终,在页面的<span>中显示了“单击后显示的内容!”字样,其效果如图2-6所示。
除了可以向$scope对象添加方法之外,还可以在方法中添加参数,多个参数同样通过逗号进行隔开。接下来,我们再通过一个示例来介绍向$scope对象添加带参数的方法。
示例2-7 添加带参数的$scope方法
(1)功能描述
在示例2-6的基础上再向控制器中添加一个名为“click_para”的带参数方法,并在页面中再添加一个<button>元素,并且将新添方法与元素的“ng-click”事件绑定,这样当单击该元素时,在元素中显示被绑定方法的参数内容。
(2)实现代码
新建一个HTML文件2-7.html,加入如代码清单2-7所示的代码。
代码清单2-7 添加带参数的$scope方法

<!doctype html>
<html ng-app="a2_7">
<head>
    <title>添加带参数的$scope方法</title>
    <script src="../Script/angular.min.js" 
            type="text/javascript"></script>
</head>
<body>
    <div ng-controller="c2_7">
        <span class="show">{{text}}</span>
        <input id="btnShow" type="button" 
               ng-click="click_show();" value="显示" />
        <input id="btnPara" type="button"
               ng-click="click_para('单击了带参数按钮!');" 
               value="带参数显示" />
    </div>
    <script type="text/javascript">
        var a2_7 = angular.module('a2_7', []);
        a2_7.controller('c2_7', ['$scope', function ($scope) {
            $scope.text = 'Hello!Angular';
            $scope.click_show = function () {
                $scope.text = "单击后显示的内容!";
            };
            $scope.click_para = function (ptext) {
                $scope.text = ptext;
            };
        }]);
    </script>
</body>
</html>

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

38ffdfbbd4fa4b4d5abe0d86ea113d48950e7603

(4)源码分析
在本示例的源码中,在构建控制器代码时,新添加一个名为“click_para”的带参方法,在该方法中将形参ptext的值设置为$scope对象“text”的属性值;而在页面中通过Angular的事件处理器,将新添加的方法与另外一个<button>元素的click事件相绑定。在绑定时,将字符串常量“单击了带参数按钮!”作为调用方法时需要传递的实参。
当单击<button>元素时便触发了click事件,在事件中调用“click_para”方法,由形参ptext接收传来的字符串常量,并将该常量值作为$scope对象“text”的属性值。由于页面中的<span>元素已通过双花括号中的表达式绑定了“text”属性值,因此,在控制器中$scope对象的“text”属性值变化后,被绑定的<span>元素显示内容将自动同步更新,最终将更新的内容显示在页面中。

2.2.4 $scope对象属性和方法的继承

继承,顾名思义,指的是一种层次间的延续关系。由于页面本身就是一个具有层次性的DOM结构模型,而Angular中的“ng-controller”指令也允许在不同的层次元素中指定控制器。因此,处于子层控制器中的$scope对象将会自动继承父层控制器中$scope对象的属性和方法。
接下来,我们通过一个示例来说明$scope对象中属性和方法的继承过程。
示例2-8 $scope对象中方法和属性的继承
(1)功能描述
在页面中添加两个具有包含关系的

元素,在父级
的控制器中添加属性和方法,而将这些属性和方法与子级
中的元素相绑定,在子级
元素中显示属性内容,在单击<button>按钮时调用父级控制器中添加的方法。
(2)实现代码
新建一个HTML文件2-8.html,加入如代码清单2-8所示的代码。
代码清单2-8 $scope对象方法和属性的继承

<!doctype html>
<html ng-app="a2_8">
<head>
    <title>$scope对象方法和属性的继承</title>
    <script src="../Script/angular.min.js" 
            type="text/javascript"></script>
</head>
<body>
    <div ng-controller="c2_8">
        <div ng-controller="c2_8_1">
            <span class="show">{{text}}</span><br />
            <span class="show">{{child_text}}</span>
            <input id="btnShow" type="button"
                ng-click="click_show();" value="继承" />
        </div>
    </div>  
    <script type="text/javascript">
        var a2_8 = angular.module('a2_8', []);
        a2_8.controller('c2_8', ['$scope', function ($scope) {
            $scope.text = 'Hello!Angular';
            $scope.click_show = function () {
                $scope.text = "单击按钮后显示的内容!";
            };
        }]);
        a2_8.controller('c2_8_1', ['$scope', function ($scope) {
            $scope.child_text = '欢迎来到 Angular 的精彩世界!';
        }]);
    </script>
</body>
</html>

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

图2-8 $scope对象方法和属性的继承
(4)源码分析
在本示例的页面代码中,我们通过“a2_8”模块分别构建了两个名称为“c2_8”和“c2_8_1”的控制器,用于管理页面中的父级和子级

元素。由于子级
元素继承了父级控制器中$scope对象的属性和方法,因此,在子级
元素中,第一个 元素绑定了父级中$scope对象的“text”属性值,<button>元素绑定了父级控制器中$scope对象的“click_show”方法,当单击该按钮时,重置“text”属性的值,并同步更新页面中绑定该属性显示的内容。
在通常情况下,在$scope对象的继承中,不仅局限于父与子的层次关系,还是一种内层继承外层的顺序关系,即最内层可以继承包含它的所有外层中$scope对象的属性和方法,而在最内层控制器中添加的新属性和方法,最外层不能访问。因此,这种继承是一种由内向外的顺序关系。
相关文章
|
4月前
|
前端开发 开发者 开发框架
JSF与Bootstrap,打造梦幻响应式网页!让你的应用跨设备,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,响应式设计至关重要,以确保不同设备上的良好用户体验。本文探讨了JSF(JavaServer Faces)与Bootstrap框架的结合使用,展示了如何构建响应式网页。JSF是一个基于Java的Web应用框架,提供丰富的UI组件和表单处理功能;而Bootstrap则是一个基于HTML、CSS和JavaScript的前端框架,专注于实现响应式设计。通过结合两者的优势,开发者能够更便捷地创建自适应布局,提升Web应用体验。然而,这种组合也有其局限性,如JSF组件库较小和较高的学习成本等,因此在选择开发框架时需综合考虑具体需求和应用场景。
51 0
|
4月前
|
开发者 前端开发 开发框架
JSF与移动应用,开启全新交互体验!让你的Web应用轻松征服移动设备,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,移动设备的普及使得构建移动友好的应用变得至关重要。尽管JSF(JavaServer Faces)主要用于Web应用开发,但结合Bootstrap等前端框架,也能实现优秀的移动交互体验。本文探讨如何在JSF应用中实现移动友好性,并通过示例代码展示具体实现方法。使用Bootstrap的响应式布局和组件可以确保JSF页面在移动设备上自适应,并提供友好的表单输入和提交体验。尽管JSF存在组件库较小和学习成本较高等局限性,但合理利用其特性仍能显著提升用户体验。通过不断学习和实践,开发者可以更好地掌握JSF应用的移动友好性,为Web应用开发贡献力量。
53 0
|
前端开发 测试技术 C++
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(进阶篇)
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(进阶篇)
336 0
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(进阶篇)
|
前端开发 JavaScript
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(入门篇)
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(入门篇)
462 0
Angular实战之使用NG-ZORRO创建一个企业级中后台框架(入门篇)
|
前端开发 JavaScript
对于Angular表达式以及重要指令的研究心得【前端实战Angular框架】
对于Angular表达式以及重要指令的研究心得【前端实战Angular框架】
对于Angular表达式以及重要指令的研究心得【前端实战Angular框架】
angular12-模型和控制器
angular12-模型和控制器
141 0
angular12-模型和控制器
angular14-控制器的定义
angular14-控制器的定义
129 0
angular14-控制器的定义
angular15-控制器的职责
angular15-控制器的职责
191 0
angular15-控制器的职责
|
前端开发
angular+h5聊天室|聊天实战angular版
最近一直在学习angular,毕竟ng在前端开发中有很庞大的用户量,值得尝试一下,几天学习下来,发现并没有想象的难,如是就利用angular全家桶技术开发了个angular-chatroom仿微信聊天室项目。
2236 0