Совместное использование двух директив AngularJS с третьим

99
7

EDIT Вот мой плун

Вот две строки в директиве myPane, которые заставляют ее сломаться.

require: '^myMainTabs',  //Comment out this line and uncomment below to break.
//require: ['^myMainTabs', '^mySubTabs'], //Comment out this line and uncomment above to fix.

Я бы хотел использовать одну и ту же директиву "myPane" для обеих этих вкладок, если это возможно.

End EDIT

Я смотрю на Руководство разработчика AngularJs на этом сайте. В нижней части я нашел то, что я хотел бы использовать для базы для вкладок.

Вот код, найденный на этой странице.

.directive('myTabs', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: function($scope) {
var panes = $scope.panes = [];

$scope.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false;
});
pane.selected = true;
};

this.addPane = function(pane) {
if (panes.length === 0) {
$scope.select(pane);
}
panes.push(pane);
};
},
templateUrl: 'my-tabs.html'
};
})
.directive('myPane', function() {
return {
require: '^myTabs',
restrict: 'E',
transclude: true,
scope: {
title: '@'
},
link: function(scope, element, attrs, tabsCtrl) {
tabsCtrl.addPane(scope);
},
templateUrl: 'my-pane.html'
};
});

То, что я сделал, применимо к моей теме компании, и теперь она выглядит как вкладки и отлично работает!

Однако у нас есть два или три разных типа вкладок, но в конце концов они могут использовать одну и ту же директиву "myPane". Я попытался изменить требование в директиве myPane на массив директив, например:

require: ['^tabType1', '^tabType2']

но для этого, как представляется, требуются оба типа директив.

Есть ли способ, чтобы директива могла использоваться другими директивами?

Что-то вроде этого:

.directive('myMainTabs', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: function($scope) {
var panes = $scope.panes = [];

$scope.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false;
});
pane.selected = true;
};

this.addPane = function(pane) {
if (panes.length === 0) {
$scope.select(pane);
}
panes.push(pane);
};
},
templateUrl: 'my-main-tabs.html'
};
})
.directive('mySubTabs', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: function($scope) {
var panes = $scope.panes = [];

$scope.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false;
});
pane.selected = true;
};

this.addPane = function(pane) {
if (panes.length === 0) {
$scope.select(pane);
}
panes.push(pane);
};
},
templateUrl: 'my-sub-tabs.html'
};
})
.directive('myPane', function() {
return {
require: ['^myMainTabs','^mySubTabs'] //Doesn't work
restrict: 'E',
transclude: true,
scope: {
title: '@'
},
link: function(scope, element, attrs, tabsCtrl) {
tabsCtrl.addPane(scope);
},
templateUrl: 'my-pane.html'
};
});

Спасибо, Дуэйн

спросил(а) 2021-01-19T17:18:37+03:00 6 месяцев, 1 неделя назад
1
Решение
64

Поскольку только одна из двух родительских директив (и, следовательно, контроллеров) будет доступна одновременно, вы можете сделать их необязательными (используя ?) И проверить, какой из них присутствует:

require: ['^?myMainTabs', '^?mySubTabs'],
...
link: function (scope, elem, attrs, ctrls) {
var tabsCtrl = ctrls[0] || ctrls[1] || null;
if (!tabsCtrl) return;

tabsCtrl.addPane(scope);
}

См. Также эту короткую демонстрацию.

ответил(а) 2021-01-19T17:18:37+03:00 6 месяцев, 1 неделя назад
46

Поскольку в вашей директиве myPane имеется массив контроллеров в вашем атрибуте require, то tabsCtrl будет представлять собой массив контроллеров. Вы можете получить к нему доступ, так как вы получите доступ к нормальному массиву:

tabsCtrl[0] --> first controller (myMainTabs)
tabsCtrl[1] --> second controller (mySubTabs)

ответил(а) 2021-01-19T17:18:37+03:00 6 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема