Angular $compile与所需控制器

18

我有一个复合列表指令,也就是说,一个列表项本身可以是一个列表。
父级指令定义了控制器:

.directive('parent', function() {
    controller: function($scope) {
    },
    link: function (scope, element, attrs) {
    }
})

列表(条目)需要父控制器,而父控制器本身可以正常工作(为什么不呢..):
.directive('list', function() {
     require: '^parent',
     link: function (scope, element, attrs, parentCtrl) {
     }
  })

同样适用于具体的项目,也没有问题:
.directive('item', function() {
    require: '^parent',
    link: function (scope, element, attrs, parentCtrl) {
    }
})

一个条目可能是一个复合体,如果是这种情况,则其本身会创建一个“列表”。这种组合是通过在链接函数中$compile(编译)列表项来完成的:

link: function (scope, element, attrs, parentCtrl) {
      ...
      $compile("<list></list>")(scope)
      ... 
}

出现了异常:
指令'list'需要控制器“parent”,但找不到该控制器!

显然,这是因为$compile函数没有提供控制器,导致无法解析‘parent’的要求。因此,我尝试手动提供控制器:

$compile("<list></list>")(scope, null, {'parent': parentCtrl});

这不会抛出异常,但在需要时仍然无法提供此控制器。

有什么想法可以使$compile函数接受外部控制器并进行评估?

3个回答

23

我刚遇到了类似的问题,解决方法似乎是先将元素添加到父级,然后再进行编译。

.directive('item', function($compile) {
  return {
    template:'<li><a ng-click="addSubList()">Create Another List</a></li>',
    require: '^parent',
    replace: true,
    link: function(scope, element, attrs, parentCtrl) {

      scope.addSubList = function() {
        var sublist = angular.element('<ul list>');
        element.find('a').append(sublist);
        $compile(sublist)(scope);
      };

    }
  };
});

请参考这个 Plunker:http://plnkr.co/edit/dASASrFbtXSMCRZKRAj5?p=preview


1
@lpiepiora 非常感谢!我也遇到了完全相同的问题,甚至没有意识到可以附加未编译的节点,然后让Angular进行编译! - Igor Pantović
提醒未来的自己:记住要先将要编译的主题“包裹”在angular.element中。当首次编译然后附加时,传递原始HTML有效,但反之则不行。 - migajek
1
不错的解决方案!它是有道理的,因为如果在编译之前它没有附加到现有的DOM上,Angular就无法找到所需的控制器,因为新元素只是一个没有父级的“自由”元素。 - Seb D.

9

为了以后参考,这里是解决方案:

在$compile函数中,可以将所需的控制器作为传递的控制器进行传输:

$compile(template)(scope, undefined, {transcludeControllers: injectedCtrl})

"injectedCtrl"是指列出指令所期望的控制器的对象,例如如果您使用require: '^dad',那么transcludeControllers看起来像这样:

 transcludeControllers: {
        dad: { //name of controller in 'require' statement
          instance: vm //instance of controller
        }
      }

请看这个例子:https://jsfiddle.net/qq4gqn6t/11/


就是这样!


2
你好,你有一个可用的 Plunkr 或其他类似的东西吗?我也在尝试做同样的事情,但是注入的控制器无法到达子项模板... - Sagi Mann
这个答案是可行的,但不完整...请查看此链接中的jsfiddle:http://stackoverflow.com/questions/34849645/how-use-transcludecontrollers-in-angularjs - tsiorn

-3
$compile(angular.element("< list>< /list >"))(scope)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接