如何退订在angularJS广播道软硬杀人事件事件.如何通过$上删除注册的函数

1 . 我们知道在jquery中,动态生成一个元素,如果要在动态生成元素的同时,动态绑定事件,可以通过live/on方法(在jquery3.0中已经废除了bind方法)。
2 . 在angularjs中,操作DOM一般在指令中完成,事件监听机制是在对于已经静态生成的dom绑定事件,而如果在指令中动态生成了DOM节点,动态生成的节点不会被JS事件监听。
举例来说:
angular.module('myapp',[])
.directive('myText',function(){
restrict:'A',
template:'&div ng-click="hello()"&Hi everyone&/div&',
link:function(scope,ele,attr){
这个指令中,会生成新的DOM节点:
ng-click="hello()"&Hi everyone&
但是如果不做处理,这里的ng-click事件并不能实现,因为事件的监听在静态html页面生成时候已经完成。那么如何给动态生成的元素,绑定事件,实现事件的动态监听呢?
3 . 通过$compile服务,编译DOM,实现动态的事件绑定
var template:'&div ng-click="hello()"&Hi everyone&/div&',
var content = $compile(template)(scope);
通过这两句,首先先编译DOM,然后用编译后的DOM加入到之前的静态节点中,就能实现动态绑定事件,之类注意,应该注入$compile service
.directive('myText',function($compile){})
完整的代码如下:
angular.module('myapp',[])
.directive('myText',function($compile){
var template:'&div ng-click="hello()"&Hi everyone&/div&',
restrict:'A',
link:function(scope,ele,attr){
ele.on("click", function() {
scope.$apply(function() {
var content = $compile(template)(scope);
element.append(content);
本文已收录于以下专栏:
相关文章推荐
angularJS动态生成的页面中,ng-click无效解决办法
今天碰到了一个这样的需求,在自己写的动态的页面中,写入的angularJS无效不能点击响应事件,以下给出代码以及解决方案
Angularjs在ng-repeat中动态为ng-click绑定不同的处理函数,动态改变ng-class
之前在angularjs中手动拼接了一段html里面加了事件,但是不生效,后来才发现动态添加的html并没有编译。
解决方法:
var template = angular....
addClass()-为每个匹配的元素添加指定的样式类名
after()-在匹配元素集合中的每个元素后面插入参数所指定的内容,作为其兄弟节点
append()-在每个匹配元素里面的末尾处插入参数内容
绑定dom元素enter事件有两种方法,个人推荐第二种
$scope.objtype={};
var e="eee";
var f="ddd"
$scope.objtype[e+''+f]=
AngularJS中的单选按钮的动态绑定十分简单,写法如下:男
女比如,我们想默认选中性别男的单选按钮,我们只需要在scope中给sex赋值为man,即scope.s...
在directive的link中有一个$http请求,当请求完成后根据返回的值动态做element.append('......');这个操作,能显示没问题,可问题是我动态组的HTML里...
说明:由于本人正在angular2或者说是angular4,只是把本人学习过程个人理解写出来,如果有写的不对的地方希望各位指出来,或者给我留言,相互学习。本人QQ:
一、新建一个项目...
angular js 中模板的使用,事件绑定以及指令与指令之间的交互
对应教学视频地址(需翻墙):angularjs教学视频
他的最新文章
讲师:董岩
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)借助AngularJS写优雅的代码 | 四火的唠叨
借助AngularJS写优雅的代码
接触还真有点碰巧,在用JQuery写数据绑定的时候,我被数据对象和DOM之间的同步整烦了,要写一大堆方法绑定和取值/设值的代码逻辑,丑得要死。简单说来,就是:
数据对象发生变更以后,要及时更新DOM树;
用户操作改变DOM树以后,要回头更新数据对象。
这个问题还是举例来说清楚一些,比如我定义了这样一个queryObj:
{name: &sally&, price: 30}
现在有这样的DOM对象:
&input type=&text& value=&sally& /&
&label&sally&/label&
1、queryObj发生变化的时候,这两个DOM对象要及时更新,一个是value需要更新,一个则是标签里面的文本需要更新。
我就得写这样的JQuery设值语句:
$(&input&).val(queryObj.name);
$(&label&).text(queryObj.name);
2、当用户操作改变input里面的值的时候,我也需要同步更新label里面的值,以及queryObj里面的值:
$(&input&).keydown(function(){
var data = $(this).val();
$(&label&).text(data);
queryObj.name =
可以想象在DOM对象很多的时候,这种绑定语句和设值语句恶心得令人发指。
就这个问题,第1条对象的变更需要及时刷新到DOM上,有好多办法,underscore.js、mustache之类的,模板+数据绑定嘛,当然,需要手动调用来更新;但是反过来的第2条,DOM变更需要及时刷新到其它DOM对象上,也要刷回数据对象,我找了一会儿,也没有看见有什么现成的实现,正火大地准备自己写一个简单的机制,这时Google到了AngularJS的&two way binding&,哈哈,暗爽,这不正是我想要的东西么?
鉴于这不是AngularJS的教程。在此我假设你有AngularJS的基础知识,否则,建议你先阅读AngularJS。
不管是MVC还是MVVM,数据绑定的过程总是惹人厌烦的,这样的事情做得越少越好;如果需要数据绑定的逆过程,这样的问题是现有MVC框架所很少考虑到的。AngularJS不但把双向绑定的事情替我做了,而且也避免了特定视图类的定义,直接使用原始的数据对象就好。
还是就上面这个问题,在写HTML标签的时候,增加ng-app和一个ng-controller的属性,至于占位符,和普通的模板机制没有什么区别:
&div ng-app ng-controller=&QueryController&&
&input type=&text& value=&{{queryObj.name}}& /&
&label&{{queryObj.name}}&/label&
并且定义一个和ng-controller同名的方法,参数名为$scope:
function QueryController($scope) {
$scope.queryObj = {name : &sally&, price : 30};
完毕了,这以后label、input和$scope.queryObj这三者就同步了,DOM变化的时候,其它二者也会被及时更新。这就是AngularJS的双向绑定。我觉得这大概是AngularJS最精华的部分。
AngularJS官网的教程上,还给了这样的说明:
从上面的例子,控制器、模板、数据模型、视图,这几个概念和之间的关系应该已经明晰了。
AngularJS遵循的设计理念,是构建UI应当用声明式的方式来(什么是声明式编程,请参阅)。值得一提的是,AngularJS引入的directive确实方便扩展了标签集,可以写出DSL样子的代码,非常非常灵活,比如:
&p&Error occurs.&/p&
这其中的Alert就是通过directive实现的自定义的标签,最终可以被解析成具备&警告&样式的html,但是,在对于directive的定义上面,就连官网的例子都是,生写html片段模板代码字符串的,用起来确实让我不够舒服。
依赖注入(Dependency Injection,DI)对于使用过Spring的程序员来说实在是再熟悉不过了,所谓依赖注入,就是把某个过程中注入值的步骤交给外部框架、容器来完成。举例来说,这样的代码:
function PhoneListCtrl($scope, $http) {
$http.get('phones/phones.json').success(function(data) {
$scope.phones =
$scope.orderProp = 'age';
$scope、$http都是需要AngularJS框架传入的服务变量,在此,参数的名字不可随意修改,因为AngularJS是根据它来判定需要依赖注入的。
服务可以自己定义,再利用依赖注入的方式加进来使用,这对于模块化和重用是很有帮助的。
AngularJS的表达式功能比较弱,不支持条件判断和流程控制,不过好在支持过滤器,这就一定程度上弥补了这个缺憾。过滤器是个很有趣的特性,让人想起了管道编程。到这里,开个玩笑,你大概也发现AngularJS真是一个到处抄袭,哦不,是借鉴各种概念和范型的东西,比如依赖注入抄Spring,标签定义抄Flex,过滤器抄Linux的管道:
{{ &lower cap string& | uppercase }}
{{ 4 | date:&MM/dd/yyyy @ h:mma& }}
既然是管道编程,那么肯定支持迭代地使用管道:
&li ng-repeat=&phone in phones | filter:query | orderBy:orderProp& class=&thumbnail&&
解耦一定是相对的,在我们使用各种绑定语句把onClick=&javascript:xxx&从DOM上拿掉的时候,我们就已经想到,总有一天,写那些DOM事件绑定的语句写烦了,一定还会拿回来:
&img ng-src=&{{img}}& ng-click=&setImage(img)&&
相应地,定义setImage:
$scope.setImage = function(imageUrl) {
$scope.mainImageUrl = imageU
无论是把这个绑定关系拿走还是拿回来,都是有道理的,选择你最倾心的方式。就我而言,我倾向于把同一模块的代码放置在一起,增加可理解性,而不在乎它的组成是DOM声明还是JavaScript解释。
另外,值得一提的是不同controller之间的通信方式,AngularJS推荐的方式是采用事件,具体说,controller是可以嵌套的,$broadcast会把事件广播给所有子controller,而$emit则会将事件冒泡传递给父controller,$on则是AngularJS的事件注册函数:
$scope.$on(&DataChange&, function (event, msg) {
$scope.$broadcast(&DataChange&, msg);
但是,这让我颇为不爽,如果我的两个视图在不同的controller内,我还非得要通过事件机制来保持同步的话,如此啰嗦,我还需要AngularJS干嘛?
吐槽归吐槽,AngularJS还是非常值得学习使用的,尤其是其中的双向绑定,用起来真是太爽了。最后附加几个有用的链接:
(比原文包含更多的东西)
文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接
不明觉厉啊--一步,二步,三步,N步,二行脚印
张映 发表于
分类目录:
标签:, , , , ,
使用angularjs,发现controller间的值传递,比较麻烦的,以后几篇文章会陆续说几种方法。
一,angularjs $broadcast $emit $on的处理思想
在一个controller里面通过事件触发一个方法,在方法里面通过$broadcast或$emit来定义一个变量,在父,子controller里面通过$on来获取。
二,实例说明angularjs $broadcast $emit $on的用法
1,html代码
&div ng-controller="ParentCtrl"&
&div ng-controller="SelfCtrl"&
&a ng-click="click()"&click me&/a&
&div ng-controller="ChildCtrl"&&/div&
&div ng-controller="BroCtrl"&&/div&
phonecatControllers.controller('SelfCtrl', function($scope) {
$scope.click = function () {
$scope.$broadcast('to-child', 'child');
$scope.$emit('to-parent', 'parent');
phonecatControllers.controller('ParentCtrl', function($scope) {
$scope.$on('to-parent', function(d,data) {
console.log(data);
//父级能得到值
$scope.$on('to-child', function(d,data) {
console.log(data);
//子级得不到值
phonecatControllers.controller('ChildCtrl', function($scope){
$scope.$on('to-child', function(d,data) {
console.log(data);
//子级能得到值
$scope.$on('to-parent', function(d,data) {
console.log(data);
//父级得不到值
phonecatControllers.controller('BroCtrl', function($scope){
$scope.$on('to-parent', function(d,data) {
console.log(data);
//平级得不到值
$scope.$on('to-child', function(d,data) {
console.log(data);
//平级得不到值
3,点击Click me的输出结果
用$broadcast赋的值,只能子级得到值;$emit赋的值,只能父级得到;而平级的什么都不能得到。
转载请注明作者:海底苍鹰地址:AngularJS教程之三 服务与依赖注入
& & & &&& & &
  在第一章里,我们知道Angular提供的标准服务组件有以下:
$http:用于处理 XMLHttpRequest
$location:提供当前URL的信息
异步请求使用,promise/deferred模块
$routeProvider:配置路由
$log:日志服务
我们看看最常用和调用后端的$http的用法:
$http有下面短方法:$http.get() $http.head() $http.post() $http.put()
$http.delete() $http.jsonp()
我们假设调用后端的REST URL是app/phones/phones.json,其返回的是一个Json:
&age&: 13,
&id&: &motorola-defy-with-motoblur&,
&name&: &Motorola DEFY\u2122 with MOTOBLUR\u2122&,
&snippet&: &Are you ready for everything life throws your
AngularJS的所有Service服务组件都是由依赖注入管理的,DI能够分离表现 数据和控制器,实现分离关注和松耦合。
控制器的代码是:
var phonecatApp =
angular.module('phonecatApp', []);
phonecatApp.controller('PhoneListCtrl',
function ($scope, $http) {
$http.get('phones/phones.json').success(function(data) {
$scope.phones =
$scope.orderProp = 'age';
phonecatApp.controller('PhoneListCtrl', function ($scope, $http) {...}
这表示创建一个名称为'PhoneListCtrl'的服务,其内容是function ($scope, $http) {...},也就是类似
var PhoneListCtrl =function ($scope, $http) {...}
Angular将PhoneListCtrl注入到控制器中,当然PhoneListCtrl也依赖于$scope和$http,它们也是一样,都是被注入器注入。
$http&实现对后端Web服务器的GET请求,URL是:&phone/phones.json,路径是相对于当前&index.html文件
当$http成功后success&方法返回一个($q)对象。参考:
我们可以使用返回的数据Data赋值到当前的作用域(胶水)$scope中。angular会侦测到JSON响应,然后转换成类似数组的格式。
创建自己的服务
  虽然AngularJS提过了很多有用的服务,但是如果你要创建一个很棒的应用,你可能还是要写自己的服务。你可以通过在模块Module api中注册一个服务工厂函数,或者通过Modeul#factory api或者直接通过模块配置函数中的$provide api来实现。
  所有的服务都符合依赖注入的原则。它们用一个唯一的名字将自己注册进AngularJS的依赖注入系统(injector),并且声明需要提供给工厂函数的依赖。
使用angular.Module api注册服务:
var myModule = angular.module('myModule',
myModule.factory('serviceId', function() {
shinyNewServiceI
//factory function body that constructs shinyNewServiceInstance
return shinyNewServiceI
使用$provide服务:
angular.module('myModule', [],
function($provide) {
$provide.factory('serviceId', function() {
var shinyNewServiceI
//factory function body that constructs shinyNewServiceInstance
return shinyNewServiceI
$的命名约定
  前缀$是表示&Angular自己提供的服务名称,如$scope或$provide等,为了防止冲突,最好避免命名自己开发的服务以为$开头。
  如果你检查一个scope内部,你也可能会发现一些属性开头也是以 $开头。这些特性被认为是私有的,并且不应该访问或修改。
下面这个代码是将$window注入到自己的服务中:
angular.module('myModule', [],
function($provide) {
$provide.factory('notify', ['$window', function(win) {
var msgs = [];
return function(msg) {
msgs.push(msg);
if (msgs.length == 3) {
win.alert(msgs.join(&\n&));
msgs = [];
这是一个通知服务,将消息发送到所有Angular提供的window窗口中显示。
  要注意的是所有AngularJS服务都是单例的。这意味着在每一个注入器中都只有一个需要的服务的实例。因为AngularJS极度讨厌全局的东西,这是符合面向对象OO。
我们经常会使用压缩简写对javascript进行缩小,以便获取更小的文件更快下载,压缩简写minfy可能对AngularJS注入有影响。用以下办法:
function PhoneListCtrl($scope, $http) {...}
PhoneListCtrl.$inject = ['$scope', '$http'];
phonecatApp.controller('PhoneListCtrl', PhoneListCtrl);
使用PhoneListCtrl.$inject 主动注入两个依赖。或者用括号符号[ ]
function PhoneListCtrl($scope, $http) {...}
phonecatApp.controller('PhoneListCtrl', ['$scope', '$http', PhoneListCtrl]);
这样之前案例控制器代码就写成了:
var phonecatApp =
angular.module('phonecatApp', []);
phonecatApp.controller('PhoneListCtrl', ['$scope',
function ($scope, $http) {
$http.get('phones/phones.json').success(function(data) {
$scope.phones =
$scope.orderProp = 'age';
$resource服务与REST
  $resource是一个依赖$Http的服务组件,它创建了一个资源对象,让你与RESTful服务器端数据源实现交互的工厂。返回的是资源对象,提供了高层次的行为,而不需要与低级别$ HTTP服务交互操作方法。需要&安装(&script src=&lib/angular/angular-resource.js&&&/script&)。具体用法见
对返回的数据进行默认的如下操作:
{method:'GET'},
{method:'POST'},
{method:'GET', isArray:true},
'remove': {method:'DELETE'},
'delete': {method:'DELETE'} };
var User = $resource('/user/:userId', {userId:'@id'});
var user = User.get({userId:123}, function() {
user.abc =
user.$save();
  User定义为资源$resource类型,小写的user是其一个实例,实际是从服务器抓取的根据id为123的一个User Json数组,那么我们下面可以对user这个实例使用上面几个默认操作,比如user.$save();。可以轻松地执行CRUD操作(创建,读取,更新,删除)。
var object = Data.get({id:123}, function() {
object.isDefault =
object.$save();
下面以phone举例返回列表:
var phonecatServices =
angular.module('phonecatServices', ['ngResource']);
phonecatServices.factory('Phone',
['$resource',
function($resource){
return $resource('phones/:phoneId.json', {}, {
query: {method:'GET', params:{phoneId:'phones'}, isArray:true}
这是从后台返回phone列表的$resource用法。节省了$http之类转换。
| 网站地图 | 设为首页}

我要回帖

更多关于 angularjs 广播事件 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信