Подтвердить что ты не робот

Как установить динамический контроллер для директив?

Обсуждение дешево, сначала покажите мои коды:

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

как достичь моей цели? спасибо за ваш ответ!

4b9b3361

Ответ 1

Теперь это возможно с AngularJS. В директиве вы просто добавляете два новых свойства, называемых controller, name, а также isolate scope здесь необходимо.

Важно отметить в директиве

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

Рабочая демонстрация для установки динамического контроллера для директив

Разметка HTML:

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

Angular Контроллер и директива:

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

В этом случае вы можете попробовать этот снимок кода ниже.

Рабочий демонстрационный пример

Разметка HTML:

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

Angular Код:

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

Ответ 2

Вот как это делается:

Внутри элемента директивы все, что вам нужно, - это атрибут, который дает вам доступ к имени контроллера: в моем случае атрибут моей карты содержит объект карты, который имеет свойство 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 и обрабатывает безопасность, когда этот маршрут поражен, но это будет работать с обычным маршрутом angular. В файле .cshtml/html вы настраиваете свой динамический контроллер, просто помещая его в качестве корневого элемента. Контроллер будет отличаться для каждого шаблона. Это создает иерархию контроллеров, которая позволяет применять дополнительную логику ко всем картам в целом, а затем конкретную логику для каждой отдельной карты. Мне все еще нужно выяснить, как я буду обрабатывать свои услуги, но этот подход позволяет вам создать динамический шаблонный и динамический контроллер для директивы, используя ng-repeat на основе имени контроллера. Это очень чистый способ выполнения этой функции, и все это самодостаточно.

Ответ 3

1- вам не нужно использовать: var parentElem = $(elem); as elem is a jquery element. This is similar to: $($('#myid'))

2- вы не можете динамически назначать контроллер, потому что директивный контроллер создается до фазы предварительной привязки.

Контроллер директивы имеет доступ к attrs, поэтому вы можете динамически выбирать, какая внутренняя функция (функции внутри вашего контроллера) в соответствии со значением вашего attrs['addIcons']

пс. note attrs['addIcons'] - это название верблюда.