2016-10-28 99 views
2

我熟悉控制器的语法 & 但我试图创建一个通用的指令,将获得项目的列表,并对每个项目我需要指定一个控制器。通过动态控制器角度指令

这是我的主要指令:

function controlPanel() { 
    var directive = { 
     restrict: 'E', 
     replace: true, 
     scope: { 
      controlPanelItems: "=sbControlPanelItems" 
     }, 
     templateUrl: 'control-panel.html', 
     link: link 
    }; 
    return directive; 

    function link(scope, element) { 
    } 

} 

这里是指令的模板:

<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> 

我的问题是与SB-控制面板项控制器属性。

当我传递变量时,角度抛出异常,当我传递简单字符串(控制器的名称)时,它的工作非常好。

这里是控制面板项指令代码:

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) { 

    } 

} 

也许有一种方法可以通过注入链接功能的控制器,然后我就只是将其穿过的范围?

+0

http://stackoverflow.com/questions/ 16253317/angularjs-turn-ng-controller-name-into-a-directive-variable –

回答

3

您可以使用$ controller服务在指令内动态实例化任何控制器,请检查此plunkr。 请记住,如果您想要现在静态指定一个控制器,则需要将其放在单引号中。

基本上代码将是这样的:

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); 

和这将是HTML

<!DOCTYPE html> 
<html> 

    <head> 
    <script data-require="[email protected]" 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

this blog entry似乎是一个无证的财产,可以让你做到你所需要的。

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); 

因此,只需在您的指令中添加一个属性名称,该属性名称将与您的控制器的名称一起使用。

<foo-directive ctrl="FirstCtrl"></foo-directive> 
<foo-directive ctrl="SecondCtrl"></foo-directive> 

如果你的指令,按照你的问题,需要从一个属性,而不是一个字符串,使用{{}}符号:

<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> 
+0

你可能想再次阅读我的问题,正如我提到的,我熟悉名称属性,问题是当我试图通过一个变量而不是一个字符串。 –

+0

在属性中使用{{}}表示法,抱歉,我误解了您的问题。 – pedromarce

+0

你可以添加一个工作的jsfiddle吗?尝试做到这一点,仍然得到一个例外 –