У меня есть две вложенные директивы и несколько контроллеров, и я хочу, чтобы контроллер ввода был вторым контроллером.
Когда я привязываю действие к какой-то кнопке, он работает, но список не отображается, кто-то знает почему?
Директива динамического контроллера
.directive("dynamicController", ["$compile", function($compile) {
return {
restrict: "A",
scope: {
dynamicController: "@"
},
compile: function(tElement, tAttrs) {
return {
pre: function preLink(scope, iElement, iAttrs, controller) {
iElement.attr("ng-controller", scope.dynamicController);
iElement.removeAttr("dynamic-controller");
$compile(iElement)(scope);
}
}
}
}
}])
V1: http://codepen.io/anon/pen/LVeaWo
V2: http://codepen.io/anon/pen/EjoJVx
[ РЕДАКТИРОВАТЬ ]
Я почти делаю это, но это еще одна проблема. У меня есть две директивы:
.directive("wrapDirective", function() {
return {
restrict: "A",
template: "<div dynamic-controller=\"Ctr1\">" +
"<button ng-click='action()'>Click</button>" +
"<ul>" +
"<li ng-repeat=\"item in list\">{{item}}</li>" +
"</ul>" +
"</div>",
scope: {
controller: "@wrapDirective"
}
}
})
а также
.directive("dynamicController", function($compile) {
return {
restrict: "A",
scope: true,
controller: "@",
name: "dynamicController"
}
})
Проблема заключается в этой строке <div dynamic-controller =\"Ctr1 \"> в warpDirective
Я не могу сделать что-то вроде этого <div dynamic-controller =\"{{controller}} \">
CodePen в обоих случаях: http://codepen.io/anon/pen/EjoJXV
Я сделал это, очень полезно было это сообщение: Dynamic NG-Controller Name
Я изменил его в соответствии с моими потребностями:
.directive('dynamicCtrl', ['$compile', '$parse', function($compile, $parse) {
return {
restrict: 'A',
terminal: true,
scope: {
dynamicCtrl: "@"
},
link: function(scope, elem, attr) {
var initContent = elem.html();
var varName = getName(elem.attr('dynamic-ctrl'));
update();
scope.$watch("dynamicCtrl", function() {
update();
})
function update() {
var wrapper = angular.element("<div></div>");
wrapper.append(initContent);
var name = $parse(varName)(scope.$parent);
wrapper.attr('ng-controller', name);
elem.empty();
elem.append(wrapper);
$compile(wrapper)(scope);
}
function getName(attr) {
var startIndex = attr.lastIndexOf("{") + 1,
endIndex = attr.indexOf("}");
return attr.substring(startIndex, endIndex);
}
}
};
}])
Вы должны использовать require
и link
для получения контроллеров родительских директив. См. Создание директив, которые обмениваются.
.directive('myDirective', function() {
return {
require: '^ngController', // <-- define parent directive
restrict: 'E',
scope: {
title: '@'
},
link: function(scope, element, attrs, ctrl) { // <-- get the controller via the link function
ctrl.doSomething();
}
};
Причина вашего кода не работает, {{}}
значение интерполяции не оценивается в вашей функции pre
ссылки. Таким образом, путем компиляции ng-controller
с неважным значением в нем возникает ошибка. Вы должны использовать iAttrs.$observe
как вы оцениваете выражение внутри {{}}
.
Код
var dynamicControllerObserver = iAttrs.$observe('dynamicController', function(newVal, oldVal) {
wrapElement.attr("ng-controller", scope.dynamicController);
wrapElement.append(iElement.html());
console.log(wrapElement)
iElement.html("");
console.log(iElement)
iElement.append(wrapElement);
$compile(wrapElement)(scope);
dynamicControllerObserver(); //destruct observe
})