zoukankan      html  css  js  c++  java
  • 七步从Angular.JS菜鸟到专家(2):Scopes

    这是"AngularJS - 七步从菜鸟到专家"系列的第二篇。

    在第一篇我们展示了如何开始搭建一个Angular应用。在这一篇里,我们要讨论一个理解AngularJS运作原理所必须的基本概念,以及你如何更好地运用它。

    在这个系列教程里,我们会开发一个NPR(美国全国公共广播电台)广播的音频播放器,它能显示Morning Edition节目里现在播出的最新故事,并在我们的浏览器里播放。完成版的Demo可以看这里。

    第二部分 Scopes

    $scope是一个把view(一个DOM元素)连结到controller上的对象。在我们的MVC结构里,这个 $scope 将成为model,它提供一个绑定到DOM元素(以及其子元素)上的excecution context。

    尽管听起来有点复杂,但 $scope 实际上就是一个JavaScript对象,controller和view都可以访问它,所以我们可以利用它在两者间传递信息。在这个 $scope 对象里,我们既存储数据,又存储将要运行在view上的函数。

    每一个Angular应用都会有一个 $rootScope。这个 $rootScope 是最顶级的scope,它对应着含有 ng-app 指令属性的那个DOM元素。

    如果页面上没有明确设定 $scope ,Angular 就会把数据和函数都绑定到这里, 第一部分中的例子就是靠这一点成功运行的。

    在这个例子里,我们将使用 $rootScope 。在main.js文件里,我们给这个scope加一个name属性。把这个函数放进 app.run函数里执行,我们就保证了它能在应用的其他部分之前被执行。你可以把app.run函数看作是Angular应用的main方法。

    1. app.run(function($rootScope) { 
    2.   $rootScope.name = "Ari Lerner"; 
    3. }); 

    现在,我们可以在view的任何地方访问这个name属性,使用模版表达式{{}},像这样:

    1. {{ name }} 

    在这个系列之后的章节里,我们会深入介绍模版表达式的语法。

    请看:

    Ari Lerner

    总之:

    要真正看到scope的强大功能,让我们给一个DOM元素加上controller,它将创建这个元素的$scope ,让我们跟这个元素互动。

    ng-controller

    要明确创建一个$scope 对象,我们就要给DOM元素安上一个controller对象,使用的是ng-controller 指令属性:

    1. <div ng-controller="MyController"
    2.   {{ person.name }} 
    3. </div

    g-controller指令给所在的DOM元素创建了一个新的$scope 对象,并将这个$scope 对象包含进外层DOM元素 的$scope 对象里。在上面的例子里,这个外层DOM元素的$scope 对象,就是$rootScope 对象。这个scope链是这样的:

    01

    现在,MyController 给我们建立了一个可以从DOM元素内部直接访问的$scope 对象。下面我们在的这个$scope 里创建一个person对象,在main.js中:

    1. app.controller('MyController', function($scope) { 
    2.   $scope.person = { 
    3.     name: "Ari Lerner" 
    4.   }; 
    5. }); 

    现在我们可以在有ng-controller=’MyController’属性的DOM元素的任何子元素里访问这个person 对象,因为它在$scope上。

    请看:

    Ari Lerner

    除了一个例外,所有scope都遵循原型继承(prototypal inheritance),这意味着它们都能访问父scope们。对任何属性 和方法,如果AngularJS在当前scope上找不到,就会到父scope上去找,如果在父scope上也没找到,就会继续向上回溯,一直 到$rootScope 上。

    唯一的例外:有些指令属性可以选择性地创建一个独立的scope,让这个scope不继承它的父scope们。

    举个例子,假设我们有一个ParentController ,含有一个person 对象,又有一个ChildController 想要访问这个对象:

    1. app.controller('ParentController', function($scope) { 
    2.   $scope.person = {greeted: false}; 
    3. }); 
    4.   
    5. app.controller('ChildController', function($scope) { 
    6.   $scope.sayHello = function() { 
    7.     $scope.person.greeted = true; 
    8.   } 
    9. }); 

    当我们在view里把ChildController 绑定到ParentController 之下,在子元素里我们就能访问ParentController 创建的父scope的属性,像访问ChildController 自己的scope中的属性一样:

    1. <div ng-controller="ParentController"
    2.   <div ng-controller="ChildController"
    3.     <input type="text" ng-model="person.name" placeholder="Name"></input
    4.     <ng-click="sayHello()">Say hello</a
    5.   </div
    6.   {{ person }} 
    7. </div

    02

    请看:

    结合进myApp

    现在,我们把 $scope 用在我们的NPR应用上。在上一篇结尾我们定义了app module,现在我们开始深入DOM结构,创建基本功能。

    像在上面的例子里展示过的那样,我们先创建一个root controller,命名为PlayerController。还有一个 RelatedController ,它将负责管理音频DOM元素、和为我们取回NPR节目的列表。

    回到main.js,现在我们就来创建这两个controller:

    1. var app = angular.module('myApp', []); 
    2.   
    3. app.controller('PlayerController', ['$scope', function($scope) { 
    4. }]); 
    5.   
    6. app.controller('RelatedController', ['$scope', function($scope) { 
    7. }]); 

    音频

    这两个controller现在还没什么功能,那么,让我们给应用先加上点声音吧。在这个教程里我们将使用HTML5的音频DOM元素,所以首先你得有个支持HTML5的浏览器(我们推荐Google Chrome)。

    这个音频DOM元素,我们既可以把它加在HTML里,又可以加在我们的controller里。不过鉴于我们主要使用controller跟这个音频DOM元素互动,把它创建在controller里更合适。

    现在我们就在PlayerController里创建一个音频DOM元素。我们要把它储存在scope上,然后——像你已经学过的那样——通过$scope对象把view和controller连接起来。

    1. app.controller('PlayerController', ['$scope', function($scope) { 
    2.   $scope.audio = document.createElement('audio'); 
    3. }]); 

    这个设定现在可能有点无聊,因为它还不能干什么。我们会在本系列的下一篇介绍“取回(fetching)”数据,现在我们先使用一个指定的.mp4网址。

    还是在这个PlayerController里,指定音频文件的src属性为一个你能访问的.mp4网址。方便起见,我们在这里使用一个储存在我们自己服务器上的NPR音频文件,不过其实你可以指向任何网址。现在设定你的音频src地址如下:

    1. app.controller('PlayerController', ['$scope', function($scope) { 
    2.   $scope.playing = false; 
    3.   $scope.audio = document.createElement('audio'); 
    4.   $scope.audio.src = '/media/npr.mp4'; 
    5. }]); 

    试试看

    Play Playing audio: false (请到英文原文测试“播放”按钮

    音频不会自己播放,我们必须让它播放。要做到这一点,我们可以简单地使用$scope.audio.play(),然后HTML5音频DOM元素就会开始播放mp4媒体流。

    我们可以给用户提供一个互动元素:创建一个按钮,把它绑定到$scope里的一个动作上。在下一篇里我们会更深入地介绍这一块,不过先看看上面例子里view的HTML:

    1. <div ng-controller="PlayerController"
    2.   <button ng-click="play()" class="button" ng-show="!playing">Play</button
    3.   <button ng-click="stop()" class="button alert" ng-show="playing">Stop</button
    4.   Playing audio: <b>{{ playing }}</b
    5. </div

    注意我们并不需要引用在scope里创建的那个音频DOM元素,因为它是当我们载入controller时在controller内部用 document.createElement(“audio”)创建的。在之后的教程里我们会重构这个部分,因为在controller里操作DOM元 素一般都不是个好主意(感谢Brad Green在评论中指出这一点。)然而为了简便,我们在这里还是保持这个controller如此。

    在view里我们已经加入了一些变量,在 $scope 上我们要管理这些变量。这里使用了一些高级概念,这些在本系列之后的教程里才会详细介绍,所以如果你不能一下子全看明白也不用担心:

    1. app.controller('PlayerController', ['$scope', function($scope) { 
    2.   $scope.playing = false; 
    3.   $scope.audio = document.createElement('audio'); 
    4.   $scope.audio.src = '/media/npr.mp4'; 
    5.   $scope.play = function() { 
    6.     $scope.audio.play(); 
    7.     $scope.playing = true; 
    8.   }; 
    9.   $scope.stop = function() { 
    10.     $scope.audio.pause(); 
    11.     $scope.playing = false; 
    12.   }; 
    13.   $scope.audio.addEventListener('ended', function() { 
    14.     $scope.$apply(function() { 
    15.       $scope.stop() 
    16.     }); 
    17.   }); 
    18. }]); 

    以上就是对Angular.js的$scope 功能的介绍。在下一章,我们会介绍Angular.js的双向数据绑定。

    本系列的官方代码库可从github上下载:

    https://github.com/auser/ng-newsletter-beginner-series.

    要将这个代码库保存到本地,请先确保安装了git,clone此代码库,然后check out其中的part2分支:

    1. git clone https://github.com/auser/ng-newsletter-beginner-series.git 
    2. git checkout -b part2

    原文链接:http://www.ng-newsletter.com/posts/beginner2expert-scopes.html

    译文链接:http://blog.jobbole.com/48593/

  • 相关阅读:
    从Oracle提供两种cube产品说开
    Sql Server DWBI的几个学习资料
    Unload Oracle data into text file
    初学Java的几个tips
    我常用的Oracle知识点汇总
    benefits by using svn
    如何在windows上使用putty来显示远端linux的桌面
    building commercial website using Microsoft tech stack
    Understand Thread and Lock
    Update google calendar by sunbird
  • 原文地址:https://www.cnblogs.com/specification/p/4642972.html
Copyright © 2011-2022 走看看