標籤:utf-8 alt 地址 影響 調用 api gets 基於 out
林炳文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資料共用、繼承、通訊使用具體解釋