Как установить динамический контроллер для директив?
Обсуждение дешево, сначала покажите мои коды:
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);
},
}
});
как достичь моей цели? спасибо за ваш ответ!
Ответы
Ответ 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']
- это название верблюда.