Javascript 动态NG控制器名称
我想根据我们加载的配置动态指定一个控制器。大概是这样的:Javascript 动态NG控制器名称,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我想根据我们加载的配置动态指定一个控制器。大概是这样的: <div ng-controller="{{config.controllerNameString}}> ... </div> global.directive('dynamicCtrl', ['$compile', '$parse',function($compile, $parse) { return { restrict: 'A', terminal: true, pri
<div ng-controller="{{config.controllerNameString}}>
...
</div>
global.directive('dynamicCtrl', ['$compile', '$parse',function($compile, $parse) {
return {
restrict: 'A',
terminal: true,
priority: 100000,
link: function(scope, elem) {
var name = $parse(elem.attr('dynamic-ctrl'))(scope);
elem.removeAttr('dynamic-ctrl');
elem.attr('ng-controller', name);
$compile(elem)(scope);
}
};
}]);
global.controller('blankCtrl',['$scope',function(tyler){
tyler.tyler = 'tyler';
tyler.tyler = 'chameleon';
}]);
您要做的是在调用任何其他指令之前运行另一个指令,从某个模型获取控制器名称删除新指令并添加ng controller
指令,然后重新编译元素
看起来是这样的:
<div ng-controller="{{config.controllerNameString}}>
...
</div>
global.directive('dynamicCtrl', ['$compile', '$parse',function($compile, $parse) {
return {
restrict: 'A',
terminal: true,
priority: 100000,
link: function(scope, elem) {
var name = $parse(elem.attr('dynamic-ctrl'))(scope);
elem.removeAttr('dynamic-ctrl');
elem.attr('ng-controller', name);
$compile(elem)(scope);
}
};
}]);
global.controller('blankCtrl',['$scope',function(tyler){
tyler.tyler = 'tyler';
tyler.tyler = 'chameleon';
}]);
然后您可以在模板中使用它,如下所示:
<div dynamic-ctrl="'blankCtrl'">{{tyler}}</div>
可能有一种方法可以插入动态ctrl
的值($interpolate
),而不是解析它($parse
),但由于某些原因,我无法让它工作。我在ng repeat中使用它,因此这是循环和子对象的改进代码:
模板:
<div class="col-xs6 col-sm-5 col-md-4 col-lg-3" ng-repeat="box in boxes">
<div ng-include src="'/assets/js/view/box_campaign.html'" ng-dynamic-controller="box.type"></div>
</div>
就我个人而言,这里的两个当前解决方案对我不起作用,因为在第一次编译元素时不知道控制器的名称,但后来在另一个摘要周期中才知道。因此,我最终使用了:
myapp.directive('dynamicController', ['$controller', function($controller) {
return {
restrict: 'A',
scope: true,
link: function(scope, elem, attrs) {
attrs.$observe('dynamicController', function(name) {
if (name) {
elem.data('$Controller', $controller(name, {
$scope: scope,
$element: elem,
$attrs: attrs
}));
}
});
}
};
}]);
是否有父控制器或这是最顶层的控制器?根据条件加载模板并在模板中设置控制器的多种方法这将有一个父控制器。最好是基于配置,而不是基于模板。如果控制器名称在配置中,我不希望将ng控制器添加到所有模板中。也可以在routeProvideradd:if(scope.src)elem.attr('src',“'+scope.src+”)中设置控制器;要支持ng include,您需要包含$parse
工厂,但没有使用它。放置位置:if(scope.src)elem.attr('src',“'+scope.src+”)?非常感谢。正是我想要的。在我的例子中,我希望传递一个$scope变量,而不是字符串。所以我只需要执行DynamicCtrl=“myScopeVariable”Nide解决方案。不过,我建议优先考虑550人,而不是10万人。这样,指令在ng控制器(优先级600)之前执行,但在ng if(优先级600)之后执行。否则,您将初始化控制器(在调用$compile(elem)(scope)期间),即使元素不在页面上(如果ng if为false)。此外,您还可以使用link函数的“attrs”参数访问元素的属性,以处理驼峰式大小写(即:attrs.dynamicCtrl)。