39

我正在尝试在 angularjs 中实现一个插件系统,该系统将允许用户配置他们将在某个页面上看到的“小部件”。每个小部件都由一个控制器和一个模板(url)定义。是否可以创建一个指令来实例化控制器,使用模板调用它并嵌入结果内容?

目标是这样的:

<div class="widget" ng-repeat="widget in widgets">
    <widget controller="widget.controller" templateUrl="widget.templateUrl"></widget>
</div>
4

1 回答 1

74

有两种方法可以做到这一点; 一个使用已经可用的辅助指令(如ngIncludeand ngController),第二个是手动的;手动版本可能会更快,但我不能确定。

简单的方法:

简单的方法是简单地创建一个具有ngControllerngInclude属性的新元素,将其附加到指令的元素,然后$compile

var html = '<div ng-controller="'+ctrl+'" ng-include="'+tpl+'"></div>';
element.append(html);
$compile( element.contents() )( scope );

手动方式:

手动方式是执行这些指令本身会依次执行的操作;这个逻辑与所做的非常相似ngView(尽管没有复杂性)。我们获取模板,将其存储在 中$templateCache,然后将其附加到 DOM。我们创建一个新的子范围并用它实例化提供的控制器并将该控制器分配给元素。最后,我们$compile

$http.get( tpl, { cache: $templateCache } )
.then( function( response ) {
  templateScope = scope.$new();
  templateCtrl = $controller( ctrl, { $scope: templateScope } );
  element.html( response.data );
  element.children().data('$ngControllerController', templateCtrl);
  $compile( element.contents() )( templateScope );
});

(请注意,这里没有垃圾收集,如果小部件发生更改,您需要实现它)

这是一个演示这两种方法的 Plunker:http ://plnkr.co/edit/C7x9C5JgUuT1yk0mBUmE?p=preview

于 2013-05-02T18:21:18.000 回答