web-dev-qa-db-fra.com

Comment définir le contrôleur dynamique pour les directives?

Parler n'est pas cher, affichez d'abord mes codes:

HTML:

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

directif:

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

});

manette:

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

cela fonctionne maintenant, lorsque je clique sur l'icône plus, la sortie de la console du navigateur "ajoute".

mais je veux définir le contrôleur dans la directive dynamiquement, comme ceci:

HTML:

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

Manette:

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

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

directive aime:

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

comment atteindre mon objectif? Merci pour votre réponse!

30
kuitos.lau

C'est maintenant possible avec AngularJS. Dans la directive, vous venez d’ajouter deux nouvelles propriétés appelées controller, propriété name et également isolate scope.

Important à noter dans la directive

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

Démonstration de travail pour la configuration du contrôleur dynamique pour les directives

Balisage HTML:

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

Contrôleur angulaire et directive:

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

Votre cas, vous pouvez essayer ceci ci-dessous des extraits de code.

Démo de travail

Balisage HTML:

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

Code angulaire:

angular.module('myApp',[]).

directive('addIcons', function(){
return {
    restrict : 'A',
    scope:{},
    controller : "@",
    name:"controllerName",    
    template:'<input type="button" value="(+) plus" ng-click="add()">'
  }
}).
controller("IconsOneCtrl",function($scope){
     $scope.add = function(){
        alert("IconsOne add ");
      }
}).
controller("IconsTwoCtrl",function($scope){
     $scope.add = function(){
        alert("IconsTwo add ");
      }
});
58
Raja Jaganathan

Voici comment cela se fait:

Dans votre élément de directive, tout ce dont vous avez besoin est un attribut qui vous donne accès au nom du contrôleur: dans mon cas, mon attribut card contient un objet card qui a une propriété name. Dans la directive, vous définissez la portée isolate sur:

scope: { card: '=' } 

Ceci isole et interpole l'objet carte dans le champ d'application de la directive. Vous définissez ensuite le modèle de directive sur: 

template: ''

cela recherche dans le contrôleur de la directive une fonction nommée getTemplateUrl et vous permet également de définir dynamiquement templateUrl. Dans le contrôleur de directive, la fonction getTemplateUrl ressemble à ceci: 

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

J'ai un contrôleur mvc qui relie le fichier .cshtml approprié et gère la sécurité lorsque cette route est atteinte, mais cela fonctionnerait également avec une route angulaire normale. Dans le fichier .cshtml/html, vous configurez votre contrôleur dynamique en le mettant simplement comme élément racine. Le contrôleur sera différent pour chaque modèle. Cela crée une hiérarchie de contrôleurs qui vous permet d'appliquer une logique supplémentaire à toutes les cartes en général, puis une logique spécifique à chaque carte. Je dois encore comprendre comment je vais gérer mes services, mais cette approche vous permet de créer un templateUrl dynamique et un contrôleur dynamique pour une directive en utilisant une répétition ng basée sur le nom du contrôleur seul. C’est un moyen très simple d’accomplir cette fonctionnalité et elle est autonome.

1
Chase Gibbons

1- vous n'avez pas besoin d'utiliser: var parentElem = $(elem); as elem is a jquery element. This is similar to: $($('#myid'))

2- vous ne pouvez pas affecter dynamiquement un contrôleur, car le contrôleur de directive est instancié avant la phase de pré-liaison. 

Le contrôleur de directive a accès aux attrs, vous pouvez donc choisir dynamiquement quelle fonction interne (fonctions à l'intérieur de votre contrôleur) en fonction de la valeur de votre attrs['addIcons']

ps. note attrs['addIcons'] est le nom du chameau. 

0
Aladdin Mhemed