我有一个自定义属性指令(即restrict: "A"
),我想将两个表达式(使用{{...}}
)作为属性传递给指令。我想将这些属性传递给指令模板,我用它来渲染两个嵌套的div
标记 - 外部标记包含ng-controller
,内部标记包含ng-include
。 ng-controller
将定义专门用于模板的控制器,ng-include
将呈现模板的HTML。
以下是显示相关摘要的示例。
HTML:
<div ng-controller="appController">
<custom-directive ctrl="templateController" tmpl="template.html"></custom-directive>
</div>
JS:
function appController($scope) {
// Main application controller
}
function templateController($scope) {
// Controller (separate from main controller) for exclusive use with template
}
app.directive('customDirective', function() {
return {
restrict: 'A',
scope: {
ctrl: '@',
tmpl: '@'
},
// This will work, but not what I want
// Assigning controller explicitly
template: '<div ng-controller="templateController">\
<div ng-include="tmpl"></div>\
</div>'
// This is what I want, but won't work
// Assigning controller via isolate scope variable from attribute
/*template: '<div ng-controller="ctrl">\
<div ng-include="tmpl"></div>\
</div>'*/
};
});
看来显式分配控制器是有效的。但是,我想通过一个隔离范围变量来分配控制器,该变量是我从位于HTML中的自定义指令内的属性获得的。
我已经在下面的Plunker中充实了上面的示例,其中列出了相关指令contentDisplay
(而不是上面的customDirective
)。如果这个例子需要更多评论澄清,请在评论中告诉我们:
使用显式控制器分配(未注释的模板代码),我实现了所需的功能。但是,当尝试通过隔离范围变量(注释模板代码)分配控制器时,它不再起作用,抛出错误'ctrl' is not a function, got string
。
我想改变控制器的原因(而不是仅仅将所有控制器都放入一个&#34;主控制器&#34;正如我在Plunker中所做的那样)是因为我想要制作我的代码更有条理以保持可读性。
以下想法可能相关:
ng-controller
标记放在模板中,而不是将其包裹在ng-include
周围。'&'
)执行函数而不是文本绑定('@'
)。ng-controller
的优先级低于ng-include
的优先级。虽然我正在寻找这个问题的直接解决方案,但我也愿意接受能够实现相同功能且相对简单的解决方法。
答案 0 :(得分:1)
我认为您不能使用template
动态编写scope
密钥,但您肯定会在link
函数中执行此操作。您可以使用一系列内置的Angular函数非常简洁地模仿:$http
,$controller
,$compile
,$templateCache
。
相关代码:
link: function( scope, element, attrs )
{
$http.get( scope.tmpl, { cache: $templateCache } )
.then( function( response ) {
templateScope = scope.$new();
templateCtrl = $controller( scope.ctrl, { $scope: templateScope } );
element.html( response.data );
element.children().data('$ngControllerController', templateCtrl);
$compile( element.contents() )( templateScope );
});
}
受到this similar answer的强烈启发。