angularjs相关知识
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>