本文也同步发表在我的公众号“我的天空”
控制器
控制器可以说是AngularJS中最重要的部分了!之前的一些示例,除了第一讲的示例以外,我们对于AngularJS的使用都集中在HTML部分,其实AngularJS是一个典型的支持MVC架构的框架,MVC是模型(Model)、视图(View)、控制(Controller)的缩写,对于HTML来说我们通常将其归于View,既一个系统展示数据的那部分。MVC的核心是将一个系统的数据展示、逻辑控制、数据源完全的分离,使得各部分之间完全没有耦合。
回到AngularJS,我们之前的示例都集中在HMTL部分,包括指令、数据初始化、表达式、HTML重复等,接下来我们来学习控制器部分,先请看以下代码:
<body ng-app="myApp">
<div ng-controller="person">
{{name}}
</div>
</body>
<script>
var app=angular.module("myApp",[]);
app.controller("person",function($scope){
$scope.name="张三";
});
</script>
示例代码AngularJS_08.html
学习以上代码,该代码与我们之前的示例代码相比增加了新知识点,而这些是AngularJS中非常关键与重要的部分,一定要理解透彻。
首先我们给ng-app指令命名了,以便在JS代码中可以对其访问。接下来,我们在div中增加了一个新的指令:ng-controller,这个便是控制器,其核心作用是将一个DOM元素(即View)与AngularJS中的controller对象进行了关联,通俗的来说,便是在AngularJS中可以以对象的方式来访问、控制该DOM元素,这样便无需用类似于domcument.getElementById()之类的代码来获取并控制HTML的元素。也许现在大家对于这点还不是太能理解,不要紧,我们继续看其js部分代码。
在js代码中,我们首先通过语句angular.module("myApp",[])定义了一个模块“app”,用以获取AngularJS的应用范围,angular.module()方法有两个参数,前一个参数对应html中的ng-app命名,后一个参数是数组,如果需要依赖外部模块的话,则将外部模块名依次写入数组中,这样在执行时就能够引用了,本例我们不需要引入外部模块,所以写为空数组(我们在后面的AngularJS路由以及AngularJS依赖注入中,将会学习外部模块的引入)。
接下来通过app.controller获取添加了名为“person”控制器的DOM元素,在本示例中为div,随后就可以通过$scope来获得该DOM元素的引用。$scope实际上是一个JavaScript对象,视图(View)和控制器(Controller)都可以访问它,所以我们可以利用它在两者之间传递信息。在本例中,可以简单的将$scope认为就是我们要改写内容的那个div。
最后,我们将$scope中的name属性设置为“张三”,而在div中,我们有一个表达式{{name}},所以在$scope中对该变量的改写就被同步到HTML上,name的值设置为“张三”,最终便在div中显示“张三”。
在AngularJS的控制器代码编写中,是不应该出现DOM元素的,一切对于DOM的操作都是通过$scope来实现的,如果你发现其代码中必须出现DOM操作语句,那么表明你的设计是不合理的,也许有时候这种写法你会觉得别扭,但是必须慢慢适应,才能感受MVC模式带来的真正好处。
自然而然的,我们立即会想到在一个页面中肯定能支持多个控制器存在,实际情况也确实如此,看以下代码:
<body ng-app="myApp">
<div ng-controller="person1">
{{name}}
</div>
<div ng-controller="person2">
<p>{{name}}</p>
</div>
</body>
<script>
var app=angular.module("myApp",[]);
app.controller("person1",function($scope){
$scope.name="张三";
});
app.controller("person2",function($scope){
$scope.name="李四";
});
</script>
示例代码AngularJS_09.html
在以上代码中,我们声明了两个控制器person1和person2,其中person2的name是显示在<P>标签中,随后将其赋予不同的值。
如果有多个控制器嵌套,那会怎么样呢?前面说过,$scope实质上是JavaScript对象,因此多个控制器嵌套,便意味着多个$scope嵌套,而$scope遵循着原型继承的原则,这意味着其可以访问父$scope,对于任何属性和方法,如果当前$scope上找不到,则会在父$scope上去找,这个和对象的处理方式是一样的,看以下代码:
<body ng-app="myApp" ng-controller="person">
职业:{{job}}
<div ng-controller="person1">
姓名:{{name}} 职业:{{myjob}}
</div>
</body>
<script>
var app=angular.module("myApp",[]);
app.controller("person",function($scope){
$scope.job="软件工程师";
});
app.controller("person1",function($scope){
$scope.name="张三";
$scope.myjob=$scope.job;
});
</script>
示例代码AngularJS_10.html
在以上代码中,person1位于person内,因此person的$scope可以看做是person1中$scope的父对象。当在person1控制器中执行$scope.myjob=$scope.job时,person1中的$scope并没有job属性,那么它会去找其父对象中(person)是否有该属性,而其父对象person的$scope中是有job属性的,其值为“软件工程师”,因此在person1中,也将显示职业为“软件工程师”。
AngularJS事件
AngularJS支持HTML元素的事件,其是以指令的形式存在的,譬如ng-click为单击事件、ng-mousemove为鼠标移动事件,看以下代码:
<body ng-app="myApp" ng-controller="person">
<div>
姓名:{{name}}职业:{{job}}
</div>
<input type="button" value="更改" ng-click="change()">
</body>
<script>
var app=angular.module("myApp",[]);
app.controller("person",function($scope){
$scope.name="张三";
$scope.job="软件工程师";
$scope.change=function(){
$scope.name="李四";
$scope.job="律师";
}
});
</script>
示例代码AngularJS_11.html
在以上代码中,我们添加了一个按钮,在其内部添加了一个事件指令ng-click,其指向person中的change()方法,而在person中的$scope,其change()方法是更改name和job的值,这样当单击按钮时,div内的姓名与职业将发生改变。
该系列的示例代码
https://github.com/panyongwow/angularJS
更多专业前端知识,请上 【猿2048】www.mk2048.com