2016-10-28 92 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嗎?嘗試做到這一點,仍然得到一個例外 –