angularjs控制器间的通信机制( $broadcast和 $emit)
在控制器里假设所有的都采用了 $on方法监听了所有事件:
$broadcast表示广播到子级控制器和后代级控制器
$emit表示事件发送到父级控制器和祖先级控制器
注:平级控制器监听得不到任何消息
示例
- html
<body ng-app="myApp">
<div ng-controller="ParentCtrl-1"> <!--//祖先级-->
<div ng-controller="ParentCtrl"> <!--//父级-->
<div ng-controller="SelfCtrl"> <!--//自己-->
<a id="mySelf" style="cursor: pointer; background-color: #b4b472; padding: 20px 40px;">click me {{data}}</a>
<div ng-controller="ChildCtrl"> <!--//子级-->
<div ng-controller="ChildCtrl-1"></div> <!--//后代级-->
</div>
</div>
<div ng-controller="BroCtrl"></div> <!--//平级-->
</div>
</div>
</body>
- js
var myApp = angular.module('myApp', []);
myApp.controller('SelfCtrl', function($scope, $rootScope) {
$scope.data = 'ok';
$('#mySelf').on('click',function () {
$scope.$broadcast('to-child', 'child');
$scope.$emit('to-parent', 'parent');
});
});
myApp.controller('ParentCtrl-1', function($scope) {
$scope.$on('to-parent', function(d,data) {
console.log('ParentCtrl-1', data); //父级能得到值
});
$scope.$on('to-child', function(d,data) {
console.log('ParentCtrl-1', data); //子级得不到值
});
});
myApp.controller('ParentCtrl', function($scope) {
$scope.$on('to-parent', function(d,data) {
console.log('ParentCtrl', data); //父级能得到值
});
$scope.$on('to-child', function(d,data) {
console.log('ParentCtrl', data); //子级得不到值
});
});
myApp.controller('ChildCtrl', function($scope){
$scope.$on('to-child', function(d,data) {
console.log('ChildCtrl', data); //子级能得到值
});
$scope.$on('to-parent', function(d,data) {
console.log('ChildCtrl', data); //父级得不到值
});
});
myApp.controller('ChildCtrl-1', function($scope){
$scope.$on('to-child', function(d,data) {
console.log('ChildCtrl-1', data); //子级能得到值
});
$scope.$on('to-parent', function(d,data) {
console.log('ChildCtrl-1', data); //父级得不到值
});
});
myApp.controller('BroCtrl', function($scope){
$scope.$on('to-parent', function(d,data) {
console.log('BroCtrl', data); //平级得不到值
});
$scope.$on('to-child', function(d,data) {
console.log('BroCtrl', data); //平级得不到值
});
});
- 结果:
点击click后得到的日志为
ChildCtrl child
ChildCtrl-1 child
ParentCtrl parent
ParentCtrl-1 parent
AngularJS 之 Factory vs Service vs Provider
出于内存性能的考虑,controller 只在需要的时候才会初始化,一旦不需要就会被抛弃。因此,每次当你切换或刷新页面的时候,Angular 会清空当前的 controller。与此同时,service 可以用来永久保存应用的数据,并且这些数据可以在不同的 controller 之间使用。
Angular 提供了3种方法来创建并注册我们自己的 service。
- Factory
- Service
- Provider
factory
用 Factory 就是创建一个对象,为它添加属性,然后把这个对象返回出来。你把 service 传进 controller 之后,在 controller 里这个对象里的属性就可以通过 factory 使用了。
myApp.factory('myFactory', function(){
var temp = 'myFactory',
service = {};
service.getTemp = function(){
console.log(temp);
return temp;
};
return service;
});
Service
Service是用"new"关键字实例化的。因此,你应该给"this"添加属性,然后 service 返回"this"。你把 service 传进 controller 之后,在controller里 "this" 上的属性就可以通过 service 来使用了。
myApp.service('myService', function(){
var temp = 'myService';
this. getTemp = function(){
console.log(temp);
};
});
Providers
Providers 是唯一一种你可以传进 .config() 函数的 service。当你想要在 service 对象启用之前,先进行模块范围的配置,那就应该用 provider。唯一的可以在你的控制器中访问的属性和方法是通过$get()函数返回内容。
myApp.provider('myProvider', function(){
this.temp = 'temp';
this. $get = function(){
var me = this;
return {
getTemp: function(){
console.log(this.temp);
},
temp: me.temp
}
};
});
myApp.config(function(myProviderProvider){
myProviderProvider.temp = 'myProvider';
});
控制器
myApp.controller('indexCtrl',['$scope', 'myFactory', 'myService', 'myProvider', function($scope, myFactory, myService, myProvider){
$scope.data = myProvider.temp;
myFactory.getTemp();
myService.getTemp();
myProvider.getTemp();
}]);
angularjs 之 $apply
Scope提供 $apply方法传播Model的变化。
几乎我们所有的代码都包在scope.apply()里面,像ng−click,controller的初始化,http的回调函数等。
使用场景
$apply()方法可以在angular框架之外执行angular JS的表达式,例如:DOM事件、setTimeout、XHR或其他第三方的库。
angularjs指令之绑定策略
当scope选项写为scope:{}这种形式的时候,就已经为指令生成了隔离作用域,现在,我们来看看绑定策略的三种形式:& 、= 、@。
= 与 @ 的不同点在于,@是针对字符串而用,但=是针对某个对象的引用。
直接上代码:
- @的demo示例
directive("direct",function(){
return{
restrict: 'ECMA',
template: '<div>指令中:{{ name }}</div>',
scope:{
name:'@forName'
}
}
})
.controller("nameController",function($scope){
$scope.Name="张三";
});
<div ng-controller="nameController">
<direct for-name="{{ Name }}"></direct>
<div>
- =的demo示例
directive("direct",function(){
return{
restrict: 'ECMA',
template: '<div>指令中:{{ case.name }}</div>',
scope:{
case:'='
}
}
})
.controller("nameController",function($scope){
$scope.data=[{name:"张三"},{name:"李四"}];
});
<div ng-controller="nameController">
<direct case="data[0]"></direct>
<direct case="data[1]"></direct>
<div>
- &的demo示例
无参情况:
.directive("direct",function(){
return{
restrict: 'ECMA',
template: '<div>{{ title }}</div>'+'<div><ul><li ng-repeat="x in contents">{{ x.text }}</li></ul></div>',
scope:{
getTitle:'&',
getContent:'&'
},
controller:function($scope){
$scope.title=$scope.getTitle(); //调用无参函数
$scope.contents=$scope.getContent(); //调用无参函数
}
}
})
.controller("nameController",function($scope){
$scope.title="标题";
$scope.contents =[{text:1234},{text:5678}];
});
<div ng-controller="nameController">
<direct get-title="title" get-content="contents"></direct>
</div>
有参情况:
.directive("direct",function(){
return{
restrict: 'ECMA',
template: '<div><input ng-model="model"/></div>'+'<div><button ng-click="show({name:model})">show</button>',
scope:{
show:'&'
}
}
})
.controller("nameController",function($scope){
$scope.showName=function(name){
alert(name);
}
});
<div ng-controller="nameController">
<direct show="showName(name)"></direct>
</div>