angularjs 1.x自定義指令之控制器與指令間的通訊
阿新 • • 發佈:2019-01-31
一、在指令中呼叫控制器裡定義的方法
//html
<div ng-controller="MyCtrl">
<loader howToLoad="loadData()">滑動載入</loader>
</div>
//定義模組
var myModule = angular.module("MyModule", []);
//controller
myModule.controller('MyCtrl', ['$scope', function($scope){
$scope.loadData=function() {
console.log("載入資料中...");
}
}]);
myModule.directive("loader", function() {
return {
restrict:"AE",//Element,Attribute
scope: true,//新建一個作用域,該作用域繼承父scope
link:function(scope,element,attrs){
//呼叫控制器裡定義的方法有以下3種方式:
//scope.loadData(); //方式1
//scope.$apply("loadData()"); //方式2
setTimeout(function(){
scope.$apply(attrs.howtoload());//方式3,推薦使用
})
}
}
});
在指令中通過scope.$apply可以完成對控制器裡方法的呼叫
使用這三種方式需要注意:指令的屬性scope為true和false時,才能呼叫成功;scope為{}時,不會成功呼叫
指令的屬性scope取值:
- scope: false,定義指令時,scope屬性預設為為false,直接使用父scope。修改父scope會改變子scope的值,同樣修改子scope也會改變父scope的值。
- scope: true,新建一個作用域。一開始是繫結在父scope中,但當修改位於自定義指令中的輸入框時,子scope就被建立並繼承父scope了。之後,修改父scope並不能影響子scope的值,而修改子scope也不會改變父scope的值。
- scope: { },建立一個新的“隔離”scope,但仍可與父scope通訊隔離的scope,通常用於建立可複用的指令,也就是它不用管父scope中的model。然而雖然說是“隔離”,但通常我們還是需要讓這個子scope跟父scope中的變數進行繫結。繫結的策略有3種:
- @:單向繫結,外部scope能夠影響內部scope,但反過來不成立
- =:雙向繫結,外部scope和內部scope的model能夠相互改變
- &:把內部scope的函式的返回值和外部scope的任何屬性繫結起來
二、在控制器中傳送訊息給指令
//html
<div ng-controller="MyCtrl">
<loader howToLoad="loadData()">滑動載入</loader>
</div>
//controller
myModule.controller('MyCtrl', ['$scope', function($scope){
$scope.loadData=function(){
$scope.$broadcast('approvalRecord.reloadData');//向子作用域傳送廣播
}
}]);
myModule.directive("loader", function() {
return {
restrict:"AE",//Element,Attribute
scope: true,//新建一個作用域,該作用域繼承父scope
function reloadData(){
//TODO
}
//接收廣播
scope.$on('approvalRecord.reloadData', function(){
reloadData();
});
}
}
});
控制器呼叫指令裡的方法,可以通過傳送廣播,在指令內接收廣播,然後在回撥方法裡執行指令中的方法