1. 程式人生 > >跟我學AngularJs:Controller數據共享、繼承、通信使用具體解釋

跟我學AngularJs:Controller數據共享、繼承、通信使用具體解釋

特殊 目的 lin 部分 屬性 獲得 white line idt

林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka

摘要:本文主講了AngularJs中的Controller中數據共享、繼承、通信的具體使用

本教程使用AngularJs版本號:1.5.3

AngularJs GitHub: https://github.com/angular/angular.js/

AngularJs下載地址:https://angularjs.org/

一、controller基礎與使用方法

AngularJS中的controller中文名就是控制器。它是一個Javascript函數(類型/類)。用來向視圖的作用域($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事件指令調用。例如以下:

var app = angular.module(‘myApp‘, []);
app.controller(‘myController‘, function($scope) {
    $scope.myClick = function(){
    	alert("click");
    }
});
然後頁面上使用:

<button ng-click= "myClick()" ></button>  
這樣就給button加入了一個點擊事件


二、controller繼承

這裏說的繼承一般說的是scope數據,這是由於子控制器的作用域將會原型繼承父控制器的作用域。

因此當你須要重用來自父控制器中的功能時,你所要做的就是在父作用域中加入對應的方法。這樣一來,自控制器將會通過它的作用域的原型來獲取父作用域中的全部方法。

例如以下實例:

<!DOCTYPE html>
<html lang="zh" ng-app="myApp">
<head>
	<meta charset="UTF-8">
	<title>AngularJS入門學習</title>
	<script type="text/javascript"  src="./1.5.3/angular.min.js"></script>
</head>
<body>
    <div ng-controller = "parentCtrl">
	    <p><input  type="text" ng-model = "value1">請輸入內容</p>
	    <h1>您輸入的內容為:{{value1}}</h1>
	      <div ng-controller = "childCtrl">
		    <button ng-click = "gerParentValue()"></button>
	      </div>
	</div>

</body>
<script type="text/javascript">
var app = angular.module(‘myApp‘, []);//獲得整個angularJS影響的html元素
app.controller(‘parentCtrl‘,function($scope){
    $scope.value2 = "我是林炳文";
});  

app.controller(‘childCtrl‘,function($scope){
    $scope.gerParentValue = function() {
    	alert($scope.value1 + $scope.value2);
    }
}); 
</script>
</html>

技術分享

這裏須要註意的是childCtrl所在的DIV一定要放在parentCtrl所在的DIV裏才會生效!

而且假設你須要從父控制器中調用子控制器的方法,那麽使用上面的代碼會錯誤發生。


三、controller之間共享數據

(1)在父級controller中定義scope,子級共用

<!DOCTYPE html>
<html lang="zh" ng-app="myApp">
<head>
    <meta charset="UTF-8">
    <title>AngularJS入門學習</title>
    <script type="text/javascript" src="./1.5.3/angular.min.js"></script>
</head>
<body>
   <div  ng-controller="paretnCtrl">
     <input type="text" ng-model="name" />
     <div ng-controller="childCtrl1">
        {{name}}
        <button ng-click="setName()">set name to jack jack jack</button>
     </div>
     <div ng-controller="childCtrl2">
        {{name}}
        <button ng-click="setName()">set name to tom tom tom</button>
     </div>
   </div>
</body>
<script type="text/javascript">
var app = angular.module(‘myApp‘, []);
app.controller(‘paretnCtrl‘, function($scope,$timeout) {
    $scope.name = "林炳文Evankaka";
});
app.controller(‘childCtrl1‘, function($scope,$timeout) {
    $scope.setName = function() {
         $scope.name = "set name to jack jack jack";
    };
});
app.controller(‘childCtrl2‘, function($scope,$timeout) {
    $scope.setName = function() {
    	$scope.name = "set name to tom tom tom";
    };
});
</script>
</html>

技術分享

(2)將數據全局共享

angularjs自身有二種,設置全局變量的方法,在加上js的設置全局變量的方法,總共同擁有三種。

要實現的功能是,在ng-app中定義的全局變量,在不同的ng-controller裏都能夠使用。
通過var 直接定義global variable。這根純js是一樣的。
用angularjs value來設置全局變量 。
用angularjs constant來設置全局變量 。


以下是使用value的方式

<!DOCTYPE html>
<html lang="zh" ng-app="myApp">
<head>
    <meta charset="UTF-8">
    <title>AngularJS入門學習</title>
    <script type="text/javascript" src="./1.5.3/angular.min.js"></script>
</head>
<body>
     <div ng-controller="childCtrl1">
        {{name}}
        <button ng-click="setName()">set name to jack jack jack</button>
     </div>
     <div ng-controller="childCtrl2">
        {{name}}
        <button ng-click="setName()">set name to tom tom tom</button>
     </div>
</body>
<script type="text/javascript">
var app = angular.module(‘myApp‘, []);
app.value(‘data‘,{‘name‘:‘我是林炳文‘});
app.controller(‘childCtrl1‘, function($scope,data) {
	$scope.name = data.name;
    $scope.setName = function() {
         $scope.name = "set name to jack jack jack";
    };
});
app.controller(‘childCtrl2‘, function($scope,data) {
	   $scope.name = data.name;
       $scope.setName = function() {
    	$scope.name = "set name to tom tom tom";
    };
});
</script>
</html>
技術分享

(3)service依賴註入

angularjs最突出的特殊之中的一個就是DI。 也就是註入。 利用service把須要共享的數據註入給須要的controller。

這是最好的方法

<!DOCTYPE html>
<html lang="zh" ng-app="myApp">
<head>
    <meta charset="UTF-8">
    <title>AngularJS入門學習</title>
    <script type="text/javascript" src="./1.5.3/angular.min.js"></script>
</head>
<body>
     <div ng-controller="childCtrl1">
        {{name}}
        <button ng-click="setName()">set name to jack jack jack</button>
     </div>
     <div ng-controller="childCtrl2">
        {{name}}
        <button ng-click="setName()">set name to tom tom tom</button>
     </div>
</body>
<script type="text/javascript">
var app = angular.module(‘myApp‘, []);
app.factory(‘dataService‘, function() {
  var service = {
     name:‘我是林炳文‘
   };
   return service;
});
app.controller(‘childCtrl1‘, function($scope,dataService) {
	$scope.name = dataService.name;
    $scope.setName = function() {
         $scope.name = "set name to jack jack jack";
    };
});
app.controller(‘childCtrl2‘, function($scope,dataService) {
	   $scope.name = dataService.name;
       $scope.setName = function() {
    	$scope.name = "set name to tom tom tom";
    };
});
</script>
</html>
技術分享

四、controller之間通信

在普通情況下基於繼承的方式已經足夠滿足大部分情況了,可是這樣的方式沒有實現兄弟控制器之間的通信方式,所以引出了事件的方式。

基於事件的方式中我們能夠裏面作用的$on,$emit,$boardcast這幾個方式來實現,當中$on表示事件監聽。$emit表示向父級以上的
作用域觸發事件。 $boardcast表示向子級以下的作用域廣播事件。

$emit僅僅能向parent controller傳遞event與data
$broadcast僅僅能向child controller傳遞event與data
$on用於接收event與data

實例一:

<!DOCTYPE html>
<html lang="zh" ng-app="myApp">
<head>
    <meta charset="UTF-8">
    <title>AngularJS入門學習</title>
    <script type="text/javascript" src="./1.5.3/angular.min.js"></script>
</head>
<body>
<div ng-app="app" ng-controller="parentCtr">
     <div ng-controller="childCtr1">childCtr1 name :
         <input ng-model="name" type="text" ng-change="change(name)" />
    </div>
     <div ng-controller="childCtr2">from childCtr1 name:
         <input ng-model="ctr1Name" />
     </div>
</div>
</body>
<script type="text/javascript">
var app = angular.module(‘myApp‘, []);
app.controller("parentCtr",function ($scope) {
    $scope.$on("Ctr1NameChange",function (event, msg) {//接收到來自子childCtr1的信息後再廣播給全部子controller
        console.log("parent", msg);
        $scope.$broadcast("Ctr1NameChangeFromParrent", msg);//給全部子controller廣播
    });
});
app.controller("childCtr1", function ($scope) {
    $scope.change = function (name) {
        console.log("childCtr1", name);
        $scope.$emit("Ctr1NameChange", name);//將信息傳遞給父controller
    };
}).controller("childCtr2", function ($scope) {
    $scope.$on("Ctr1NameChangeFromParrent",function (event, msg) { //監聽來自父controller的信息
        console.log("childCtr2", msg);
        $scope.ctr1Name = msg;
    });
});
</script>
</html>
技術分享

實例二:

<!DOCTYPE html>
<html lang="zh" ng-app="myApp">
<head>
    <meta charset="UTF-8">
    <title>AngularJS入門學習</title>
    <script type="text/javascript" src="./1.5.3/angular.min.js"></script>
</head>
<body>
<div ng-controller="ParentCtrl">                <!--父級-->
    <div ng-controller="SelfCtrl">              <!--自己-->
         <button ng-click="click()">click me</button>
        <div ng-controller="ChildCtrl">
        	
        </div>   <!--子級-->
    </div>
    <div ng-controller="BroCtrl">
    	
    </div>         <!--平級-->
</div>
</body>
<script type="text/javascript">
var app = angular.module(‘myApp‘, []);
app.controller(‘SelfCtrl‘, function($scope) {
  $scope.click = function () {
    $scope.$broadcast(‘to-child‘, ‘child‘);
    $scope.$emit(‘to-parent‘, ‘parent‘);
  }
});

app.controller(‘ParentCtrl‘, function($scope) {
  $scope.$on(‘to-parent‘, function(event,data) {
    console.log(‘ParentCtrl‘, data);	   //父級能得到值
  });
  $scope.$on(‘to-child‘, function(event,data) {
    console.log(‘ParentCtrl‘, data);	   //子級得不到值
  });
});

app.controller(‘ChildCtrl‘, function($scope){
  $scope.$on(‘to-child‘, function(event,data) {
    console.log(‘ChildCtrl‘, data);		 //子級能得到值
  });
  $scope.$on(‘to-parent‘, function(event,data) {
    console.log(‘ChildCtrl‘, data);		 //父級得不到值
  });
});

app.controller(‘BroCtrl‘, function($scope){  
  $scope.$on(‘to-parent‘, function(event,data) {  
    console.log(‘BroCtrl‘, data);		  //平級得不到值  
  });  
  $scope.$on(‘to-child‘, function(event,data) {  
    console.log(‘BroCtrl‘, data);		  //平級得不到值  
  });  
});
</script>
</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 不要在全局範圍


參考文章:

http://www.jianshu.com/p/1e1aaf0fd30a

http://cnodejs.org/topic/54dd47fa7939ece1281aa54f

http://www.html-js.com/article/1847

http://blog.51yip.com/jsjquery/1601.html

http://www.cnblogs.com/CraryPrimitiveMan/p/3679552.html?utm_source=tuicool&utm_medium=referral

http://www.cnblogs.com/whitewolf/archive/2013/04/16/3024843.html

跟我學AngularJs:Controller數據共享、繼承、通信使用具體解釋