angular:conctroller的数据共享、继承、通信

来源:互联网 发布:软件合作开发协议书 编辑:程序博客网 时间:2024/05/16 05:21

转载:http://blog.csdn.NET/evankaka

一、基础知识

  AngularJS中的controller中文名就是控制器,用来向视图的作用域($scope)添加额外的功能。而且每个controller都有自己的scope, 同时也可以共享他们父controller的scope内的数据。

(1)给作用域对象设置初始状态

var app = angular.module('myApp', []);  app.controller('myController', function($scope) {      $scope.inputValue = "林炳文Evankaka";  }); 

上面我们设置了一个inputValue,如果要在html页面中使用,就可以直接用{{inputValue}},如下:

<h1>您输入的内容为:{{inputValue}}</h1>

当然,你也可以将此数据双向绑定到一个input、select等,如下:

<input  type="text" ng-model = "inputValue">  

(2)给作用域对象增加行为

AngularJS作用域对象的行为是由作用域的方法来表示的。这些方法是可以在模板或者说视图中调用的。这些方法和应用模型交互,并且能改变模型。任何赋给作用域的方法,都能在模板或者说视图中被调用,并且能通过表达式或者ng事件指令调用。如下:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. var app = angular.module('myApp', []);  
  2. app.controller('myController', function($scope) {  
  3.     $scope.myClick = function(){  
  4.         alert("click");  
  5.     }  
  6. });  
然后页面上使用:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <button ng-click"myClick()" ></button>    
这样就给button添加了一个点击事件


二、controller继承

这里说的继承一般说的是scope数据,这是因为子控制器的作用域将会原型继承父控制器的作用域。因此当你需要重用来自父控制器中的功能时,你所要做的就是在父作用域中添加相应的方法。这样一来,自控制器将会通过它的作用域的原型来获取父作用域中的所有方法。

如下实例:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <!DOCTYPE html>  
  2. <html lang="zh" ng-app="myApp">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title>AngularJS入门学习</title>  
  6.     <script type="text/javascript"  src="./1.5.3/angular.min.js"></script>  
  7. </head>  
  8. <body>  
  9.     <div ng-controller = "parentCtrl">  
  10.         <p><input  type="text" ng-model = "value1">请输入内容</p>  
  11.         <h1>您输入的内容为:{{value1}}</h1>  
  12.           <div ng-controller = "childCtrl">  
  13.             <button ng-click = "gerParentValue()"></button>  
  14.           </div>  
  15.     </div>  
  16.   
  17. </body>  
  18. <script type="text/javascript">  
  19. var app = angular.module('myApp', []);//获得整个angularJS影响的html元素  
  20. app.controller('parentCtrl',function($scope){  
  21.     $scope.value2 = "我是林炳文";  
  22. });    
  23.   
  24. app.controller('childCtrl',function($scope){  
  25.     $scope.gerParentValue = function() {  
  26.         alert($scope.value1 + $scope.value2);  
  27.     }  
  28. });   
  29. </script>  
  30. </html>  


这里需要注意的是childCtrl所在的DIV一定要放在parentCtrl所在的DIV里才会生效!而且如果你需要从父控制器中调用子控制器的方法,那么使用上面的代码会发生错误。


三、controller数据之间的共享

(1)在父级controller中定义scope,子级共用

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <!DOCTYPE html>  
  2. <html lang="zh" ng-app="myApp">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title>AngularJS入门学习</title>  
  6.     <script type="text/javascript" src="./1.5.3/angular.min.js"></script>  
  7. </head>  
  8. <body>  
  9.    <div  ng-controller="paretnCtrl">  
  10.      <input type="text" ng-model="name" />  
  11.      <div ng-controller="childCtrl1">  
  12.         {{name}}  
  13.         <button ng-click="setName()">set name to jack jack jack</button>  
  14.      </div>  
  15.      <div ng-controller="childCtrl2">  
  16.         {{name}}  
  17.         <button ng-click="setName()">set name to tom tom tom</button>  
  18.      </div>  
  19.    </div>  
  20. </body>  
  21. <script type="text/javascript">  
  22. var app = angular.module('myApp', []);  
  23. app.controller('paretnCtrl', function($scope,$timeout) {  
  24.     $scope.name = "林炳文Evankaka";  
  25. });  
  26. app.controller('childCtrl1', function($scope,$timeout) {  
  27.     $scope.setName = function() {  
  28.          $scope.name = "set name to jack jack jack";  
  29.     };  
  30. });  
  31. app.controller('childCtrl2', function($scope,$timeout) {  
  32.     $scope.setName = function() {  
  33.         $scope.name = "set name to tom tom tom";  
  34.     };  
  35. });  
  36. </script>  
  37. </html>  

(2)将数据全局共享

angularjs自身有二种,设置全局变量的方法,在加上js的设置全局变量的方法,总共有三种。要实现的功能是,在ng-app中定义的全局变量,在不同的ng-controller里都可以使用。
通过var 直接定义global variable,这根纯js是一样的。
用angularjs value来设置全局变量 。
用angularjs constant来设置全局变量 。

下面是使用value的方式

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <!DOCTYPE html>  
  2. <html lang="zh" ng-app="myApp">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title>AngularJS入门学习</title>  
  6.     <script type="text/javascript" src="./1.5.3/angular.min.js"></script>  
  7. </head>  
  8. <body>  
  9.      <div ng-controller="childCtrl1">  
  10.         {{name}}  
  11.         <button ng-click="setName()">set name to jack jack jack</button>  
  12.      </div>  
  13.      <div ng-controller="childCtrl2">  
  14.         {{name}}  
  15.         <button ng-click="setName()">set name to tom tom tom</button>  
  16.      </div>  
  17. </body>  
  18. <script type="text/javascript">  
  19. var app = angular.module('myApp', []);  
  20. app.value('data',{'name':'我是林炳文'});  
  21. app.controller('childCtrl1', function($scope,data) {  
  22.     $scope.name = data.name;  
  23.     $scope.setName = function() {  
  24.          $scope.name = "set name to jack jack jack";  
  25.     };  
  26. });  
  27. app.controller('childCtrl2', function($scope,data) {  
  28.        $scope.name = data.name;  
  29.        $scope.setName = function() {  
  30.         $scope.name = "set name to tom tom tom";  
  31.     };  
  32. });  
  33. </script>  
  34. </html>  

(3)service依赖注入

angularjs最突出的特殊之一就是DI, 也就是注入, 利用service把需要共享的数据注入给需要的controller。这是最好的方法

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <!DOCTYPE html>  
  2. <html lang="zh" ng-app="myApp">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title>AngularJS入门学习</title>  
  6.     <script type="text/javascript" src="./1.5.3/angular.min.js"></script>  
  7. </head>  
  8. <body>  
  9.      <div ng-controller="childCtrl1">  
  10.         {{name}}  
  11.         <button ng-click="setName()">set name to jack jack jack</button>  
  12.      </div>  
  13.      <div ng-controller="childCtrl2">  
  14.         {{name}}  
  15.         <button ng-click="setName()">set name to tom tom tom</button>  
  16.      </div>  
  17. </body>  
  18. <script type="text/javascript">  
  19. var app = angular.module('myApp', []);  
  20. app.factory('dataService', function() {  
  21.   var service = {  
  22.      name:'我是林炳文'  
  23.    };  
  24.    return service;  
  25. });  
  26. app.controller('childCtrl1', function($scope,dataService) {  
  27.     $scope.name = dataService.name;  
  28.     $scope.setName = function() {  
  29.          $scope.name = "set name to jack jack jack";  
  30.     };  
  31. });  
  32. app.controller('childCtrl2', function($scope,dataService) {  
  33.        $scope.name = dataService.name;  
  34.        $scope.setName = function() {  
  35.         $scope.name = "set name to tom tom tom";  
  36.     };  
  37. });  
  38. </script>  
  39. </html>  
四、controller之间通信

在一般情况下基于继承的方式已经足够满足大部分情况了,但是这种方式没有实现兄弟控制器之间的通信方式,所以引出了事件的方式。基于事件的方式中我们可以里面作用的$on,$emit,$boardcast这几个方式来实现,其中$on表示事件监听,$emit表示向父级以上的
作用域触发事件, $boardcast表示向子级以下的作用域广播事件。

$emit只能向parent controller传递event与data
$broadcast只能向child controller传递event与data
$on用于接收event与data

实例一:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <!DOCTYPE html>  
  2. <html lang="zh" ng-app="myApp">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title>AngularJS入门学习</title>  
  6.     <script type="text/javascript" src="./1.5.3/angular.min.js"></script>  
  7. </head>  
  8. <body>  
  9. <div ng-app="app" ng-controller="parentCtr">  
  10.      <div ng-controller="childCtr1">childCtr1 name :  
  11.          <input ng-model="name" type="text" ng-change="change(name)" />  
  12.     </div>  
  13.      <div ng-controller="childCtr2">from childCtr1 name:  
  14.          <input ng-model="ctr1Name" />  
  15.      </div>  
  16. </div>  
  17. </body>  
  18. <script type="text/javascript">  
  19. var app = angular.module('myApp', []);  
  20. app.controller("parentCtr",function ($scope) {  
  21.     $scope.$on("Ctr1NameChange",function (event, msg) {//接收到来自子childCtr1的信息后再广播给所有子controller  
  22.         console.log("parent", msg);  
  23.         $scope.$broadcast("Ctr1NameChangeFromParrent", msg);//给所有子controller广播  
  24.     });  
  25. });  
  26. app.controller("childCtr1", function ($scope) {  
  27.     $scope.change = function (name) {  
  28.         console.log("childCtr1", name);  
  29.         $scope.$emit("Ctr1NameChange", name);//将信息传递给父controller  
  30.     };  
  31. }).controller("childCtr2", function ($scope) {  
  32.     $scope.$on("Ctr1NameChangeFromParrent",function (event, msg) { //监听来自父controller的信息  
  33.         console.log("childCtr2", msg);  
  34.         $scope.ctr1Name = msg;  
  35.     });  
  36. });  
  37. </script>  
  38. </html>  

实例二:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <!DOCTYPE html>  
  2. <html lang="zh" ng-app="myApp">  
  3. <head>  
  4.     <meta charset="UTF-8">  
  5.     <title>AngularJS入门学习</title>  
  6.     <script type="text/javascript" src="./1.5.3/angular.min.js"></script>  
  7. </head>  
  8. <body>  
  9. <div ng-controller="ParentCtrl">                <!--父级-->  
  10.     <div ng-controller="SelfCtrl">              <!--自己-->  
  11.          <button ng-click="click()">click me</button>  
  12.         <div ng-controller="ChildCtrl">  
  13.               
  14.         </div>   <!--子级-->  
  15.     </div>  
  16.     <div ng-controller="BroCtrl">  
  17.           
  18.     </div>         <!--平级-->  
  19. </div>  
  20. </body>  
  21. <script type="text/javascript">  
  22. var app = angular.module('myApp', []);  
  23. app.controller('SelfCtrl', function($scope) {  
  24.   $scope.click = function () {  
  25.     $scope.$broadcast('to-child', 'child');  
  26.     $scope.$emit('to-parent', 'parent');  
  27.   }  
  28. });  
  29.   
  30. app.controller('ParentCtrl', function($scope) {  
  31.   $scope.$on('to-parent', function(event,data) {  
  32.     console.log('ParentCtrl', data);       //父级能得到值  
  33.   });  
  34.   $scope.$on('to-child', function(event,data) {  
  35.     console.log('ParentCtrl', data);       //子级得不到值  
  36.   });  
  37. });  
  38.   
  39. app.controller('ChildCtrl', function($scope){  
  40.   $scope.$on('to-child', function(event,data) {  
  41.     console.log('ChildCtrl', data);      //子级能得到值  
  42.   });  
  43.   $scope.$on('to-parent', function(event,data) {  
  44.     console.log('ChildCtrl', data);      //父级得不到值  
  45.   });  
  46. });  
  47.   
  48. app.controller('BroCtrl', function($scope){    
  49.   $scope.$on('to-parent', function(event,data) {    
  50.     console.log('BroCtrl', data);         //平级得不到值    
  51.   });    
  52.   $scope.$on('to-child', function(event,data) {    
  53.     console.log('BroCtrl', data);         //平级得不到值    
  54.   });    
  55. });  
  56. </script>  
  57. </html>  
输出结果:


$emit和$broadcast可以传多个参数,$on也可以接收多个参数。

在$on的方法中的event事件参数,其对象的属性和方法如下

事件属性目的event.targetScope发出或者传播原始事件的作用域event.currentScope目前正在处理的事件的作用域event.name事件名称event.stopPropagation()一个防止事件进一步传播(冒泡/捕获)的函数(这只适用于使用`$emit`发出的事件)event.preventDefault()这个方法实际上不会做什么事,但是会设置`defaultPrevented`为true。直到事件监听器的实现者采取行动之前它才会检查`defaultPrevented`的值。event.defaultPrevented如果调用
五、对于controller层的一些建议

1、controller层不要涉及到太多的业务逻辑,可以将公用的部分抽取到Service层

2、service层:主要负责数据交互和数据处理、处理一些业务领域上的逻辑;
3、controller层:主要负责初始化$scope的变量用于传递给view层,并且处理一些页面交互产生的逻辑;
4、当一个功能是设计远程API调用、数据集、业务领悟复杂逻辑、将会大量重复的运算方法时就可以考虑将代码以service形式注入controller层。

5、controller 里的 $scope 是唯一页面数据来源。不要直接修改 DOM。

6、controller 不要在全局范围

0 0
原创粉丝点击