[英]pass dynamic controller to angular directive
i am familiar with the syntax of controller & name but i'm trying to create a generic directive that will get a list of items and for each item i need to specify a controller. 我熟悉控制器和名称的语法,但是我试图创建一个通用指令,该指令将获取项目列表,并且需要为每个项目指定一个控制器。
This is my main directive: 这是我的主要指令:
function controlPanel() {
var directive = {
restrict: 'E',
replace: true,
scope: {
controlPanelItems: "=sbControlPanelItems"
},
templateUrl: 'control-panel.html',
link: link
};
return directive;
function link(scope, element) {
}
}
Here is the directive template: 这是指令模板:
<sb-control-panel-item ng-repeat="controlPanelItem in controlPanelItems"
sb-title="controlPanelItem.title"
sb-template-url="controlPanelItem.templateUrl"
sb-control-panel-item-controller="controlPanelItem.controller"></sb-control-panel-item>
My issue is with the sb-control-panel-item-controller attribute. 我的问题是sb-control-panel-item-controller属性。
Angular throws exception when i'm passing variable, it work's great when i'm passing simple string (the name of the controller). 当我传递变量时,Angular会引发异常,当我传递简单字符串(控制器的名称)时,它的工作效果很好。
Here is the code of the control-panel-item directive: 这是control-panel-item指令的代码:
function controlPanelItem() {
var directive = {
restrict: 'E',
replace: true,
scope: {
title: '=sbTitle',
templateUrl: '=sbTemplateUrl'
},
templateUrl: 'control_panel_item.html',
controller: '@',
name: 'sbControlPanelItemController',
link: link
};
return directive;
function link(scope, iElement, iAttributes, controller) {
}
}
Maybe there is a way to inject the controller through the link function and then i'll just pass it through the scope? 也许有一种方法可以通过链接功能注入控制器,然后将其通过示波器?
You can use the $controller service to instantiate whatever controller dynamically inside the directive, check this plunkr . 您可以使用$ controller服务在指令内动态实例化任何控制器,请检查此plunkr 。 Just bear in mind that if you wanted to specify a controller statically now, you would need to enclose it in single quotes. 请记住,如果要立即静态指定控制器,则需要将其用单引号引起来。
Basically the code would be like: 基本上,代码是这样的:
function MainCtrl() {
this.firstCtrl = 'FirstCtrl';
this.secondCtrl = 'SecondCtrl';
}
function FirstCtrl() {
this.name = 'First Controller';
}
function SecondCtrl() {
this.name = 'Second Controller';
}
function fooDirective() {
return {
scope: {
ctrl: '='
},
template: '<div>{{foo.name}}</div>',
controller: ['$controller', '$scope', function($controller, $scope) {
var foo = $controller($scope.ctrl, {$scope: $scope});
return foo;
}],
controllerAs: 'foo',
link: function ($scope, $element, $attrs, $ctrl) {
console.log($scope.ctrl);
}
};
}
angular
.module('app', [])
.directive('fooDirective', fooDirective)
.controller('MainCtrl', MainCtrl)
.controller('FirstCtrl', FirstCtrl)
.controller('SecondCtrl', SecondCtrl);
and this would be the HTML 这就是HTML
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js@1.5.8" data-semver="1.5.8" src="https://code.angularjs.org/1.5.8/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="app" ng-controller="MainCtrl as main">
<h1>
Test
</h1>
<foo-directive ctrl="main.firstCtrl">
"name: " {{foo.name}}
</foo-directive>
<foo-directive ctrl="main.secondCtrl">
{{foo.name}}
</foo-directive>
</body>
</html>
======================================================================== WRONG OLD ANSWER ================================================== ====================== 错误的旧答案
From this blog entry seems to be an undocumented property that allows you to do exactly what you need. 在此博客条目中似乎是一个未记录的属性,可让您完全执行所需的操作。
function FirstCtrl() {
this.name = 'First Controller';
}
function SecondCtrl() {
this.name = 'Second Controller';
}
function fooDirective() {
return {
scope: {},
name: 'ctrl',
controller: '@',
controllerAs: 'foo',
template: '<div></div>',
link: function ($scope, $element, $attrs, $ctrl) {
}
};
}
angular
.module('app', [])
.directive('fooDirective', fooDirective)
.controller('FirstCtrl', FirstCtrl)
.controller('SecondCtrl', SecondCtrl);
So all you need to do in your directive is add a property name linked to the attribute you will use with the name of your controller. 因此,您在指令中需要做的就是添加一个属性名称,该名称链接到将与控制器名称一起使用的属性。
<foo-directive ctrl="FirstCtrl"></foo-directive>
<foo-directive ctrl="SecondCtrl"></foo-directive>
If your directive, as per your question, needs to be from a property rather than a string, use {{}} notation: 如果您的指令(根据您的问题)需要来自属性而不是字符串,请使用{{}}表示法:
<sb-control-panel-item ng-repeat="controlPanelItem in controlPanelItems"
sb-title="controlPanelItem.title"
sb-template-url="controlPanelItem.templateUrl"
sb-control-panel-item-controller="{{controlPanelItem.controller}}"></sb-control-panel-item>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.