$ compile在Angular指令中不起作用

时间:2015-07-19 21:22:32

标签: javascript angularjs

每次我的模型更改时,使用此Angular指令

,将新的HTML项附加到页面:

app.directive('helloWorld', function($compile) {
    return {
        restrict: 'AE',
        replace: true,

        scope:{
            arrayItem: '=ngModel'
        },
        link: function ($scope, ele, attrs) {
            $scope.$watch( 'ngModel' , function(){
                ele.html('<div ng-click="sendLike({{arrayItem.data.timeline_content}})" class="timeline-item"> Hello {{arrayItem2.data.timeline_content}} </div>');
                $compile(ele.contents())($scope);
            });
        }
    };
});

这是HTML视图:

<hello-world ng-repeat="arrayItem in arr" ng-model="arrayItem"></hello-world>

但是动态生成的HTML内部的ng-click不起作用。实际上重新编译这个新添加的部分是行不通的。

更新

这就是我想要实现的目标: enter image description here

实际上我想创建一个聊天应用程序。存储在Array中的消息,我必须将该数组绑定到HTML视图。如果我点击每条消息,我需要在控制器内部触发一个alert()。我的控制器是这样的:

app.controller("timelineCtrl", function ($scope) {
    $scope.arr={};

    $scope.sendLike = function (id) {
        alert(id);
    };
         .
         .
         .
}

以jQuery方式,我只是使用DOM操作方法并为每条消息添加新标签,但在Angular方式中,我必须将该数组绑定为ng-model或类似的东西。

乍一看,我意识到设计一个指令应该是一个好主意,在模块内部我可以访问主范围并使用该指令做所需的事情,我希望该指令内的更改应该投影到HTML视图但是它失败了而像ng-click这样的东西并不适用于动态创建的标签。

1 个答案:

答案 0 :(得分:2)

无论是否有指令,您都可以通过两种方式实现这一目标。

让我们在没有指令的情况下开始;我们假设您在控制器中有一个数组。

<div ng-controller="timelineCtrl" class="timelineframe">
  <div ng-repeat="post in timeline | orderBy:'-lineNumber'" class="post">
    <div ng-click="sendAlert(post)">
      <span class="postnumber">{{::post.lineNumber}}:</span>
      <span class="message">{{::post.message}}</span>
    </div>
  </div>
</div>

只要将对象添加到$ scope.timeline,就可以为其分配lineNumber,我们可以使用角度OrderBy按反向lineNumber顺序对方向进行排序(使用{ {1}})。 -会将特定帖子发送给该功能。在我们的绑定中,我们使用$scope.sendAlert(post)来表示这些是一次性绑定,即不是需要独立于数组进行监视的值。这可以提高大型列表的性能。

使用指令,我们可以通过制作一个呈现特定帖子的指令,并将该帖子作为属性传递,以非常类似的方式实现此目的。

::
如果你愿意的话,你可以用类似的方式将这个时间轴包装在一个指令中。其中任何一个都将完成相同的任务,循环遍历您的数据,对其进行排序以使最新的帖子位于顶部,并在数组更改时进行更新。在非指令方法中,app.directive('timelinePost', function() { return { restrict: 'AE', scope:{ post: '=' }, template: '<div ng-click="postCtrl.sendAlert()"> <span class="postnumber">{{::postCtrl.post.lineNumber}}:</span> <span class="message">{{::postCtrl.post.message}}</span> </div>', controller: 'postController', controllerAs: 'postCtrl', bindToController: true }; app.controller("postController", function(){ var self = this; //save reference to this self.sendAlert = function(){ //the specific post is available here as self.post, due to bindToController }; }; //usage in HTML: <div ng-controller="timelineCtrl" class="timelineframe"> <div ng-repeat="post in timeline | orderBy:'-lineNumber'" class="post"> <timeline-post post='post'></timeline-post> </div> </div> 处理timelineCtrl函数;在指令方法中,它由指令控制器$scope.sendAlert处理。

请注意,这是一份基于您所描述内容的粗略草稿以及过去两天内各个帖子的信息。我还没有创建一个数据集来迭代完全测试,但这里的逻辑应该让你开始。