AngularJS开发指南11:AngularJS的model,controller,view详解

model

model这个词在AngularJS中,既可以表示一个(比如,一个叫做phonesmodel,它的值是一个包含多个phone的数组)对象,也可以表示应用中的整个数据模型,这取决于我们所讨论的AngularJS文档中的上下文。

在AngularJS中,一个模型就是AngularJS作用域对象中的任何一个可取的属性。属性的名字就是模型的标示符。它的值可以是任意的Javascript对象(包括数组和原始对象)。

将Javascript对象变成模型的唯一要求是这个对象必须是AngularJS作用域的一个属性引用。这个引用既可以显式也可以隐式地创建。

你可以像下面这样显式地创建一个作用域属性,引用Javascript对象:

  • 在Javascript代码中直接将一个对象赋给作用域对象属性;这种情况常见于控制器中:

     function MyCtrl($scope) {
         // create property ‘foo‘ on the MyCtrl‘s scope
         // and assign it an initial value ‘bar‘
         $scope.foo = ‘bar‘;
     }
  • 在模板中使用表达式:

    <button ng-click="{{foos=‘ball‘}}">Click me</button>

  • 在模板中使用ngInit指令(只适用于实例,不推荐在实际应用中使用):

    <body ng-init=" foo = ‘bar‘ ">

当处理下面这样的模板结构时,AngularJS会隐式地(通过创建一个作用域对象的属性,并将合适地值赋给它来实现)创建模型。

  • 从input, select, textarea或者其他表单元素中:

    <input ng-model="query" value="fluffy cloud">

   上面的代码,在当前作用域中创建了一个叫做query的模型,值被设置成"fluffy cloud"。

  • ngRepeater的迭代声明中:

    <p ng-repeat="phone in phones"></p>

   上面代码,为phones数组中的每一项都创建了一个子作用域。并且在各自的作用域中创建了一个叫做phone的对象(模型),它的值被设置成数组中当前的值。

Controller

在AngularJS中,控制器是一个Javascript函数,用来增强除了根作用域以外的作用域实例的。当你或者AngularJS本身通过scope.$new创建一个新的子作用域对象时,有一个选项能让你将它当做参数传递给控制器。这能使AngularjS将控制器和这个作用域联系起来,增强作用域的行为。

控制器用于:

  • 设置好作用域对象的初始状态。
  • 给作用域对象增加行为。

给作用于对象设置初始状态:

一般来说,当你创建应用时,你需要对它的作用域设置初始状态。

AngularJS将对作用域对象调用控制器的构造函数(从某种意义上来说就像使用Javascript的apply方法一样),以此来设置作用域的初始状态。这意味着AngularJS不会创建控制器类型的实例(不会使用new方法来调用控制器构造函数)。控制器总是对某个已存在的作用域对象调用。

你可以通过创建一个模型属性来设置初始作用域的初始状态。 比如:

function GreetingCtrl($scope) { $scope.greeting = ‘Hola!‘; }

GreetingCtrl控制器,创建了一个模板中可以调用的,叫greeting的模型。

给作用域对象增加行为

AngularJS作用域对象的行为是由作用域的方法来表示的。这些方法是可以在模板或者说视图中调用的。这些方法和应用的模型交互,并且能改变模型。

如我们在模型那一章所说的,任何对象(或者原生的类型)被赋给作用域后就会变成模型。任何赋给作用域的方法,都能在模板或者说视图中被调用,并且能通过表达式或者ng事件指令调用。(比如,ngClick)

我们如何正确地使用控制器呢?

总的来说,一个控制器不应该做太多工作。它应该只包含单个视图的业务逻辑。

保持控制器职责单一的最常见做法是将那些不属于控制器的工作抽离到服务中,然后通过依赖注入,在控制器中使用这些服务。这在依赖注入服务的章节中会详细讨论。

不要用控制器干下面的事情:

  • 控制器应该只关心业务逻辑。DOM操作(表现层逻辑)通常会把测试弄得很难。将任何表现层逻辑放到控制器中都会显著地增加对业务逻辑的测试难度。AngularJS提供dev_guide.templates.databinding用来自动进行DOM操作。如果你需要手动操作DOM,将表现层的逻辑抽离到指令中。
  • 对输入格式化 — 你应该用AngularJS的表单控制来实现格式化。.
  • 对输出格式化 — 你应该用AngularJS的过滤器实现。.
  • 实例化组件或者控制其它组件的生命周期(比如创建一个服务的实例).

你可以显示地用scope.$new来将控制器和作用域对象显示地联系起来,或者隐式地通过ngController指令或者$route服务来联系。

最后,我们用实例来讲解controller:

为了阐述AngularJS的控制器组件的运行原理,让我们来创建一个拥有下面这些组件的小应用:

  • 一个有两个按钮和一条消息的模板
  • 一个叫spice的字符串模型。
  • 一个拥有两个方法的控制器SpicyCtrl。这两个方法是用来设置spice的值。
<body ng-controller="SpicyCtrl">
 <button ng-click="chiliSpicy()">Chili</button>
 <button ng-click="jalapenoSpicy()">Jalapeño</button>
 <p>The food is {{spice}} spicy!</p>
</body>

function SpicyCtrl($scope) {
 $scope.spice = ‘very‘;
 $scope.chiliSpicy = function() {
   $scope.spice = ‘chili‘;
 }
 $scope.jalapenoSpicy = function() {
  $scope.spice = ‘jalapeño‘;
 }
}

模板中的消息(p元素中的内容)包含了一个对spice模型的绑定,它初始的字符串是“very”。这个spice模型会被设置成 chili 或者 jalapeno,这取决于哪个按钮会被点击。消息会通过数据绑定自动更新。例子中有下面这些需要注意:

  • ngController指令是用来(隐式地)为模板创建作用域的。并且使用指令中指定的spicyCtrl控制器来增强这个作用域。
  • 对作用域对象赋予一个新的属性会创建或者更新模型。
  • 控制器中的所用方法都能在模板中调用(在body元素或者子元素中).
  • AngularJS的老版本(1.0RC之前的)会自动给作用域对象原型添加方法,现在不会了。所有的方法都必须手动添加到作用域。

控制器方法可以接受参数,比如:

<body ng-controller="SpicyCtrl">
 <input ng-model="customSpice" value="wasabi">
 <button ng-click="spicy(‘chili‘)">Chili</button>
 <button ng-click="spicy(customSpice)">Custom spice</button>
 <p>The food is {{spice}} spicy!</p>
</body>

function SpicyCtrl($scope) {
 $scope.spice = ‘very‘;
 $scope.spicy = function(spice) {
   $scope.spice = spice;
 }
}

SpicyCtrl控制器中,只定义了一个叫spicy的方法,它接受一个叫做spice的参数。和这个控制器相关的模板在第一个按钮事件中传递了一个chili常量给控制器中的方法,在第二个按钮中传递一个模型属性。

控制器继承示例:

AngularJS中的控制器继承是基于作用域的继承的,比如:

<body ng-controller="MainCtrl">
 <p>Good {{timeOfDay}}, {{name}}!</p>
 <div ng-controller="ChildCtrl">
   <p>Good {{timeOfDay}}, {{name}}!</p>
   <p ng-controller="BabyCtrl">Good {{timeOfDay}}, {{name}}!</p>
</body>

function MainCtrl($scope) {
 $scope.timeOfDay = ‘morning‘;
 $scope.name = ‘Nikki‘;
}

function ChildCtrl($scope) {
 $scope.name = ‘Mattie‘;
}

function BabyCtrl($scope) {
 $scope.timeOfDay = ‘evening‘;
 $scope.name = ‘Gingerbreak Baby‘;
}

注意我们是如何在模板中嵌套我们的ngController指令的。这个模板结构会使得AngularJS为视图创建四个作用域:

  • 根作用域
  • MainCtrl作用域, 它包含了模型timeOfDay和模型name。
  • ChildCtrl作用域,它继承了上层作用域的timeOfDay,复写了name。
  • BabyCtrl作用域,复写了MainCtrl中定义的timeOfDay和ChildCtrl中的name。

控制器的继承和模型继承是同一个原理。

注意:常规的原型继承对控制器来说不起作用。因为正如我们之前提到的,控制器不是直接实例化的,而是对作用域对象调用的。

View

在AngularJS中,视图(view)指的是浏览器加载和渲染之后,并且在AngularJS,根据模板、控制器、模型信息修改之后的DOM。

在AngularJS对MVC的实现中,视图是知道模型和控制器的。视图知道模型的双向绑定,视图通过指令知道控制器,比如ngControllerngView指令,也可以通过绑定知道,比如{{someControllerFunction()}}。通过这些方式,视图可以调用相应控制器中的方法。

加油!

时间: 2024-10-08 03:52:28

AngularJS开发指南11:AngularJS的model,controller,view详解的相关文章

AngularJS开发指南7:AngularJS本地化,国际化,以及兼容IE低版本浏览器

AngularJS本地化,国际化 国际化,简写为i18n,指的是使产品快速适应不同语言和文化. 本地化,简称l10n,是指使产品在特定文化和语言市场中可用. 对开发者来说,国际化一个应用意味着将所有的文字和其他因地区而异的数据从应用中抽离出来. 本地化意味着为这些抽离的数据和文字提供翻译和转变成本地的格式. 目前,AngularJS支持日期,数字和货币的国际化和本地化. 另外,AngularJS还通过ngPluralize指令支持本地多元化. 所有的AngularJS本地化组件都依赖于$loca

Angularjs开发指南

Angularjs开发指南:http://docs.ngnice.com/guide Angularjs中文网:http://www.apjs.net/

AngularJS开发指南:表达式

---恢复内容开始--- 表达式是类似Javascript的代码片段,通常在绑定中用到,写在双大括号中如{{表达式}}.表达式是用$parse方法来处理的. 下面是一些合法的AngularJS表达式 1+2 3*10 | currency user.name AngularJS表达式 与Javascript表达式的比较 你可能会认为AngularJS视图中的表达式就是Javascript表达式,这种认识不完全对,因为AngularJS不会用Javascript的eval()函数去执行表达式. 不

[@Controller]3 详解@CookieValue,@PathVariable,@RequestBody,@RequestHeader,@RequestParam

[@Controller]3 详解@CookieValue,@PathVariable,@RequestBody,@RequestHeader,@RequestParam 转载:http://blog.sina.com.cn/s/blog_6d3c1ec601017q4l.html 下列参数一般都和@RequestMapping配合使用.   A.@CookieValue org.springframework.web.bind.annotation.CookieValue public @in

html5开发手机打电话发短信功能,html5的高级开发,html5开发大全,html手机电话短信功能详解

在很多的手机网站上,有打电话和发短信的功能,对于这些功能是如何实现的呢.其实不难,今天我们就用html5来实现他们.简单的让你大开眼界. HTML5 很容易写,但创建网页时,您经常需要重复做同样的任务,如创建表单.在这...有 HTML5 启动模板.空白图片.打电话和发短信.自动完成等等,帮助你提高开发效率的同时,还带来了更炫的功能.好了,我们今天就来做一做看看效果吧!! 看代码: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitio

iOS开发——使用Charles进行https网络抓包详解

我在前面两篇博客中<网络抓包工具Charles的介绍与使用><iOS开发--使用Charles进行http网络抓包详解>对Charles的http抓包进行了详细的讲解.今天我们来实现一下进行https的抓包,比http抓包稍微麻烦一点. (1)https初级的配置请参考<网络抓包工具Charles的介绍与使用>中的https配置部分. (2)由于目前iOS9更改了对于https网络的安全机制,所以还需要在iPhone上安装一个证书,安装方式如下: 在iPhone的Saf

HTML5移动开发之路(14)——Video标签详解

本文为 兄弟连IT教育 机构官方 HTML5培训 教程,主要介绍:HTML5移动开发之路(14)--Video标签详解 一.使用技巧 在HTML5中可以使用<audio>或者<video>标签播放html5媒体,使用方式如下: [html] view plaincopyprint? <video src="move.mp4"></video> video标签中有很多属性,例如controls属性可以控制是否有控制台. [html] vie

AngularJS开发指南16:AngularJS构建大型Web应用详解

AngularJS是由Google创建的一种JS框架,使用它可以扩展应用程序中的HTML功能,从而在web应用程序中使用HTML声明动态内容.在该团队工作的软件工程师Brian Ford近日撰写了一篇blog,分享了如何使用AngularJS构建大型Web应用的经验.这些经验对于使用其他JS框架构建大型应用的开发者也极具借鉴意义. 这篇blog特别关注的是大型应用程序,作者首先给出的建议是,尽量不要让应用变得太巨大.而应该编写小型.功能专注的.模块化的部分,然后逐渐把它们组合起来,变得越来越大,

AngularJS开发指南6:AngularJS表单详解

表单控件(input, select, textarea )是用来获取用户输入的.表单则是一组有联系的表单控件的集合. 用户能通过表单和表单控件提供验证的服务,知道自己的输入是否合法.这样能让用户交互变得友好,因为用户能通过反馈来修正自己的错误.不过,虽然客户端的验证能够起到很大作用,但也很容易被绕过,所以不能完全依靠客户端验证. 要建立安全的应用,服务器端验证还是必不可少的. 了解AngularJS双向绑定的关键在于了解ngModel指令.这个指令通过动态将model和view互相映射,来实现