指令中的ng-repeat正在指令之外链接

时间:2014-06-01 16:50:15

标签: angularjs angularjs-directive

(很多类似的问题/答案,但无法找到解决方案)

尝试创建嵌套指令。问题是内部指令被置于外部指令之上。

angular.module('mayofest14ClientApp')
  .controller('OrderCtrl', ['$scope',
    function ($scope) {
      $scope.order = {
        activities: [
          {formattedTime: '2014-03-04', performedBy: 'matt', action: 'Action', comment: 'Some comment'},
        ],
      };

    }
  ])
  .directive('orderActivity', [function () {

    return {
      scope: {
        activities: '=',
      },
      replace:true,
      restrict: 'E',
      template:
        '<div class="order_activity">' +
        '   <table>' +
        '       <caption>order_id History</caption>' +
        '       <thead>' +
        '           <tr>' +
        '               <th>Date</th>' +
        '           </tr>' +
        '       </thead>' +
        '       <tbody>' +
        '           <p ng-repeat="record in activities" record="record">Order activity {{record.action}} (This is where I want to call a nested directive)</p>' +
        '' +
        '       </tbody>' +
        '   </table>' +
        '</div>',
    };
  }]);

HTML,

<order-activity activities="order.activities"></order-activity>

结果是,带有p的{​​{1}}标记出现在ng-repeat指令中的模板之前。

我已经阅读了有关使用transclude,搞乱替换的内容,有些人提到使用orderActivity$timeout来调整顺序。后者特别显得凌乱,我无法找到一个很好的例子。

基本上,我该怎样做才能以正确的顺序进行渲染?

我是否应该构建链接函数来生成模板,并写入活动中的所有记录&#39;它是自我并避免重复&#39;?

哦,这是Angular 1.2.16

感谢。

1 个答案:

答案 0 :(得分:0)

(不确定这是一个很好的解决方案)

真正的动机是调用内在指令。我在问题中使用了p标签只是为了简化。

无论如何,我似乎通过确保在external指令之前编译内部指令来解决这个问题。我通过使用$compile$interpolate以及为内部指令创建范围来完成此操作。

我的外在指令:

angular.module('mayofest14ClientApp')
.directive('orderActivity', ['$compile', function ($compile) {
    var head = 
        '<div class="order_activity">' +
        '   <table>' +
        '       <caption>order_id History</caption>' +
        '       <thead>' +
        '           <tr>' +
        '               <th>Date</th>' +
        '               <th>Performed By</th>' +
        '               <th>Action</th>' +
        '               <th>Comment(s)</th>' +
        '           </tr>' +
        '       </thead>' +
        '       <tbody>\n';
    var body = '';
    var foot = '        </tbody>' +
        '   </table>' +
            '</div>';

        return {
            scope: {
                activities: '=',
        },
        restrict: 'E',
        link: function (scope, element, attrs) {
            for (var i = 0; i<scope.activities.length; i++) {
                var itemScope = scope.$new(true);
            itemScope.record=scope.activities[i];
                body += $compile('<order-activity-item record="record"></order-activity-item>')(itemScope).html();
            }

            console.log("Compiling order-activity");
            element.html(
                $compile(head+body+foot)(scope)
            );
        }
    };
}]);

我的内心指示:

angular.module('mayofest14ClientApp')
.directive('orderActivityItem', ['$compile', '$interpolate', function ($compile, $interpolate) {
    var template = '<tr><td>{{record.date}}</td><td>{{record.performedBy}}</td><td>{{record.action}}</td><td>{{record.comment}}</td></tr>';
    return {
        scope: {
            record: '=',
        },
        restrict: 'E',
        replace: true,
        compile: function compile(element, attributes) {
            console.log('orderItem (compile)');
            return {
                pre: function preLink(scope, element, attributes) {
                    console.log('orderItem (pre-link)');
                    element.html($interpolate(template)(scope));
                },
                post: function postLink(scope, element, attributes) {
                    console.log('orderItem (post-link)');
                }
            };
        },
    };
}]);

所以这里的重要部分是: - 我正在创建一个范围,并给它内部指令读取的record对象 - 在内部指令compile函数中,$interpolate将值放入html中,然后编译它 - 编译和插值的HTML返回到外部指令的链接 - 然后构建外部指令。

我还没有检查内存错误或其他任何内容,我也不知道这样做是否会以负面影响性能。

我选择外部/内部指令的原因是我希望内部指令对其进行操作(单击以修改等等),这就是我如何在适当的OO设计中布置对象。不确定指令是否应该反映OO架构。

我在其他地方看过的解决方案使用$watch$on s,有些甚至使用了$timeout s。后者看起来很混乱,不可预测,而前者似乎很奇怪。无论如何,我真的无法让那些人工作。