AngularJs $compile服务

正常情况(即非动态插入 DOM 对象)下,ng-click 这样的指令之所以有效(即点击之后能调用注册在可见作用域里的方法),是因为 angular 在 compiling phase(编译阶段)将宿主 DOM 对象(即加入了 ng-click 指令的 DOM 对象)绑定在当前作用域内了。

换言之,当前作用域知道有这个绑定了 ng-click 的 DOM 对象存在,所以 ng-click 才会起作用。

而在你的例子里,HTML 片段是在 compiling phase 后动态插入到 DOM 树中的,即便你写了 ng-click,当前的作用域也不知道这个指令的存在,所以才会无效。

因此,当你动态插入 HTML 片段的时候,要手动调用 $compile 服务并将这个 DOM 对象绑定给当前的作用域(或其他可见作用域,这要看你的应用逻辑了),具体方法如下:

// 在某一个 controller 中,假设用 jQuery 动态插入一个 HTML 片段……$('selector').html(
  $compile(    '<button ng-click="submitForm()">' + 'Submit' + '</button>'
  )($scope)
);

注意要先注入 $compile 服务。

另外,这种方式明显太“恶心”,还有一个更好的办法(但是大量动态插入会有性能损耗)就是利用 ng-repeat 指令,举个例子:

<!-- 在要动态插入的地方…… --><div class="form-control" ng-repeat="fragment in fragments">
  <button ng-click="submitForm()">{{fragment.text}}</button></div>

这里的 fragments 就是一个空数组(初始状态),所以一开始这里 ng-repeat 不会有任何作用,然后你写一个方法来触发动态插入的动作,把一个类似 { text: 'Submit' } 这样的对象 push 到这个空数组中,ng-repeat 就会“帮”你把 DOM 对象插入了,并且 ng-repeat 本身就会重新 compile 内涵的 DOM 对象,因此 ng-click 会如你所愿的生效。


ng 中的模板是很重要,也很强大的一个机制,自然少不了单独运用它的方法。不过,即使是单独使用,也是和 DOM 紧密相关的程度:

  • 定义时必须是有 HTML 标签包裹的,这样才能创建 DOM 节点

  • 渲染时必须传入 $scope

之后使用 $compile 就可以得到一个渲染好的节点对象了。当然, $compile 还要做其它一些工作,指令处理什么的。

var TestCtrl = function($scope, $element,$compile){
  $scope.a = '123';
  $scope.set = function(){    var tpl = $compile('<p>hello {{ a }}</p>');    var e = tpl($scope);
    $element.append(e);
  }
}


AngularJS学习笔记

转载于:https://my.oschina.net/waston/blog/626859

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值