简体   繁体   English

$ compile在Angular指令中不起作用

[英]$compile doesn't work inside Angular directive

with this Angular directive every time my model changes, new HTML item appended to the page: 每当我的模型更改时,使用此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);
            });
        }
    };
});

And this is HTML view: 这是HTML视图:

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

But ng-click inside dynamically generated HTML doesn't work. 但是在动态生成的HTML内进行ng-click无效。 actually recompiling of this new added section does not works. 实际上,重新编译此新添加的部分无效。

UPDATE: 更新:

this is what i want to achieve: 这是我想要实现的目标: 在此处输入图片说明

in fact i want to create a chat Application. 实际上,我想创建一个聊天应用程序。 messages stored inside an Array and i have to bind that array to the HTML view. 消息存储在数组中,我必须将该数组绑定到HTML视图。 if i click on every message, i need to an alert() fired inside the controller. 如果我单击每条消息,则需要在控制器内部触发alert()。 my controller is like this: 我的控制器是这样的:

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

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

in the jQuery way, i simply use DOM manipulation methods and add new tags for each message but in Angular way i have to bind that array as a ng-model or something like that. 以jQuery的方式,我只是使用DOM操作方法并为每条消息添加新标签,但是以Angular的方式,我必须将该数组绑定为ng-model或类似的东西。

at first glance, i realize that designing a directive should be a good idea and inside module i can access to main scope and do needed thing with that directive and i expect that changes inside that directive should projected to HTML view but it fails and things like ng-click doesn't work for dynamically created tags. 乍一看,我意识到设计指令应该是一个好主意,并且在模块内部我可以访问主作用域并使用该指令执行所需的操作,并且我希望该指令内的更改应投射到HTML视图,但失败并且类似ng-click不适用于动态创建的标签。

There are two ways that you could accomplish this, with or without a directive. 有或没有指令,有两种方法可以完成此操作。

Let's start without a directive; 让我们从没有指令开始; we'll assume that you have an array in the controller. 我们假设您在控制器中有一个数组。

<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>

whenever an object is added to $scope.timeline, it can be assigned a lineNumber , and we can use angular OrderBy to sort the direction in reverse lineNumber order (using - ). 每当将对象添加到$ scope.timeline时,都可以为其分配一个lineNumber ,并且我们可以使用angular OrderBy以相反的lineNumber顺序对方向进行排序(使用- )。 The $scope.sendAlert(post) will send the specific post to the function. $scope.sendAlert(post)会将特定的帖子发送到函数。 in our bindings, we use :: to indicate that these are one time bindings, ie not values that need to be monitored independently of the array. 在绑定中,我们使用::来表示这些是一次性绑定,即不是需要独立于数组进行监视的值。 This can improve performance on large lists. 这样可以提高大型列表的性能。

using a Directive, we can accomplish this in a very similar manner, by making a Directive that renders a specific post, and passing the post in as a property. 使用伪指令,我们可以通过创建呈现特定帖子的伪指令,并将该帖子作为属性传递,以非常相似的方式来实现。

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>

you could further wrap this timeline in a directive in a similar manner, if you so desired. 如果需要,您可以按照类似的方式进一步将此时间轴包装在指令中。 Either of these will accomplish the same task, of looping through your data, ordering it so that the newest post is at the top, and updating whenever the array changes. 这两种方法都可以完成相同的任务,即遍历数据,对其进行排序以使最新的帖子位于顶部,并在数组发生更改时进行更新。 In the non-directive method, the timelineCtrl handles the $scope.sendAlert function; 在非指令方法中, timelineCtrl处理$scope.sendAlert函数; in the directive method, it is handled by the directive controller postController . 在指令方法中,它由指令控制器postController处理。

Please note, this is a rough draft based on what you have described and the information from various posts over the last 2 days. 请注意,这是一个粗略的草稿,它基于您所描述的内容以及最近两天来自各个帖子的信息。 I haven't created a dataset to iterate through to test thoroughly, but the logic here should get you started. 我尚未创建要进行迭代以进行彻底测试的数据集,但是此处的逻辑应该可以帮助您入门。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM