如何为指令设置动态控制器?

时间:2013-10-18 07:54:34

标签: angularjs angularjs-directive

谈话很便宜,首先显示我的代码:

HTML:

<div add-icons="IconsCtrl">
</div>

指令:

angular.module('attrDirective',[]).directive('addIcons', function($compile){
return {
    restrict : 'A',
    controller : "IconsCtrl"
    },
    link : function (scope, elem , attrs, ctrl) {
        var parentElem = $(elem);
        var icons = $compile("<i class='icon-plus' ng-click='add()'></i>)(scope);
        parentElem.find(".accordion-heading").append(icons);
    },
}

});

控制器:

function IconsCtrl($scope){
  $scope.add = function(){
    console.log("add");
  };
}

现在它可以工作,当我点击加号图标时,浏览器控制台输出“添加”。

但我想动态地将控制器设置为指令,如下所示:

HTML:

<div add-icons="IconsOneCtrl">
</div>
<div add-icons="IconsTwoCtrl">
</div>

控制器:

function IconsOneCtrl($scope){
       $scope.add = function(){
        console.log("IconsOne add");
       };
    }

function IconsTwoCtrl($scope){
    $scope.add = function(){
        console.log("IconsTwo add");
    }
}

指令喜欢:

angular.module('attrDirective',[]).directive('addIcons', function($compile){
return {
    restrict : 'A',
    controller : dynamic set,depends on attrs.addIcons
    },
    link : function (scope, elem , attrs, ctrl) {
        var parentElem = $(elem);
        var icons = $compile("<i class='icon-plus' ng-click='add()'></i>)(scope);
        parentElem.find(".accordion-heading").append(icons);
    },
}
});

如何实现我的目标?谢谢你的回答!

3 个答案:

答案 0 :(得分:58)

现在可以使用AngularJS。在指令中,您只需添加两个名为的新属性 controller属性以及name在此非常需要。

指令

中需要注意的重要事项
isolate scope

Working Demo for Setting Dynamic controller for Directives

HTML标记:

scope:{}, //isolate scope
controller : "@", // @ symbol
name:"controllerName", // controller names property points to controller.

角度控制器和指令:

<communicator controller-name="PhoneCtrl" ></communicator>
<communicator controller-name="LandlineCtrl" ></communicator>

您的情况下,您可以尝试以下代码段。

Working Demo

HTML标记:

var app = angular.module('myApp',[]).
directive('communicator', function(){
return {
    restrict : 'E',
    scope:{},
    controller : "@",
    name:"controllerName", 
    template:"<input type='text' ng-model='message'/><input type='button' value='Send Message' ng-click='sendMsg()'><br/>"          
  }   
}).
controller("PhoneCtrl",function($scope){
 $scope.sendMsg = function(){
     alert( $scope.message + " : sending message via Phone Ctrl");
    }
}).
controller("LandlineCtrl",function($scope){
    $scope.sendMsg = function(){
        alert( $scope.message + " : sending message via Land Line Ctrl ");
    }
})

Angular Code:

<div add-icons controller-name="IconsOneCtrl">
</div>
<div add-icons controller-name="IconsTwoCtrl">
</div>

答案 1 :(得分:1)

这是如何完成的:

在您的指令元素中,您只需要一个属性,可以访问控制器的名称:在我的情况下,我的卡属性包含一个具有name属性的卡对象。在指令中,您将隔离范围设置为:

scope: { card: '=' } 

将卡对象隔离并插入指令范围。然后,将指令模板设置为:

template: ''

这指向指令的控制器,用于名为getTemplateUrl的函数,并允许您动态设置templateUrl。在指令控制器中,getTemplateUrl函数如下所示:

controller: ['$scope', '$attrs', function ($scope, $attrs) { 
    $scope.getTemplateUrl = function () { return '/View/Card?cardName=' + 
        $scope.card.name; }; }],

我有一个mvc控制器,它链接正确的.cshtml文件,并在命中此路由时处理安全性,但这也适用于常规的角度路由。在.cshtml / html文件中,您只需将根元素设置为动态控制器即可。每个模板的控制器都不同。这将创建一个控制器层次结构,允许您将一般逻辑应用于所有卡,然后为每个卡应用特定逻辑。我仍然需要弄清楚我将如何处理我的服务,但这种方法允许您使用基于控制器名称的ng-repeat为指令创建动态templateUrl和动态控制器。这是完成此功能的一种非常简洁的方式,它是完全独立的。

答案 2 :(得分:0)

1-您不需要使用:var parentElem = $(elem); as elem is a jquery element. This is similar to: $($('#myid'))

2-您无法动态分配控制器,因为指令控制器在预链接阶段之前被实例化。

指令控制器可以访问attrs,因此您可以根据attrs['addIcons']

的值动态选择内部函数(控制器内的函数)

PS。注意attrs['addIcons']是骆驼命名。