ng-repeat 在指令中不起作用

ng-repeat not working within directive

我为 drop.js 创建了一个 Angular 包装器,它是一个 javascript 弹出窗口库。

除了使用 ng-repeat 外,在 drop 指令中一切正常,包括正常的 Angular 绑定。

这是一个屏幕截图,请注意弹出窗口的内容有一个绑定到控制器的值,但 ng-repeat 没有显示任何数据。

这是完整的 plunker:http://plnkr.co/edit/plcUAWCRQ009blhY3nqF?p=preview

这是一个用法示例:

<button>
    button text {{someValue}}

    <ul>
      <li ng-repeat="thing in things">button text {{thing.code}} - {{thing.name}}</li>
    </ul>

    <drop classes='classes' position='position'>

        <div>
            Hello {{ $parent.someValue}}
          <br>

          <ul>
            <!-- here is the problem, ng-repeat does not compile correctly -->
            <li ng-repeat="thing in $parent.things">{{thing.code}} - {{thing.name}}</li>
          </ul>
        </div>
    </drop>
</button>

指令代码如下:

.directive('drop', function ($compile) {
  return {
    restrict: 'E',
    replace: true,
    transclude: true,
    scope: {
      classes: '=?',
      constrainToScrollParent: '=?',
      constrainToWindow: '=?',
      position: '=?',
      openOn: '=?'
    },
    template: '<div><div ng-transclude></div></div>',
    link: function (scope, element, attrs) {
      var drop;
      var target = element[0].parentElement;
      var compiled = $compile(element[0].children[0].innerHTML);

      var initDrop = function() {
        if (drop) {
          drop.destroy();
        }

        // some default values go here if they weren't passed in....

        drop = new Drop({
          target: target,
          content: compiled(scope)[0],
          classes: scope.classes,
          constrainToScrollParent: scope.constrainToScrollParent,
          constrainToWindow: scope.constrainToWindow,
          position: scope.position,
          openOn: scope.openOn
        });
      }

      initDrop();

      // clean up element
      element[0].innerHTML = '';

      // some watchers go here....
    }
  }
});

你可以试试 transcludeFn。我不确定您是否需要 prepost 函数,或者是否可以将 transclude 函数直接放在 link(postLink)中。 Plunker

.directive('drop', function ($compile) {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        scope: {
          classes: '=?',
          constrainToScrollParent: '=?',
          constrainToWindow: '=?',
          position: '=?',
          openOn: '=?'
        },
        link: {
          pre: function(scope, element, attrs, ctrl, transclude){
            transclude(scope, function(clone, scope) {
              element.append(clone);
            });
          },
          post:function (scope, element, attrs) {
              var drop;
              var target = element[0].parentElement;
              var compiled = $compile(element[0].children[0]);

              var initDrop = function() {
                if (drop) {
                  drop.destroy();
                }

                if (typeof scope.classes == 'undefined') scope.classes = 'drop-theme-arrows-bounce';
                if (typeof scope.constrainToScrollParent == 'undefined') scope.constrainToScrollParent = true;
                if (typeof scope.constrainToWindow == 'undefined') scope.constrainToWindow = true;
                if (typeof scope.position == 'undefined') scope.position = 'top center';
                if (typeof scope.openOn == 'undefined') scope.openOn = 'click';

                drop = new Drop({
                  target: target,
                  content: compiled(scope)[0],
                  classes: scope.classes,
                  constrainToScrollParent: scope.constrainToScrollParent,
                  constrainToWindow: scope.constrainToWindow,
                  position: scope.position,
                  openOn: scope.openOn
                });
              }

            initDrop();

            // clean up element
            element[0].innerHTML = '';

            ...
            }
        }
    }
});