Я создал полный пример с целью описания этой проблемы. Мое фактическое приложение даже больше, чем представленная демонстрация, и есть больше сервисов и директив, управляемых каждым контроллером. Это приводит к еще большему количеству повторений кода. Я попытался поместить некоторые комментарии кода для разъяснений, PLUNKER: http://plnkr.co/edit/781Phn?p=preview
Повторяющаяся часть:
routerApp.controller('page1Ctrl', function(pageFactory) {
var vm = this;
// page dependent
vm.name = 'theOne';
vm.service = 'oneService';
vm.seriesLabels = ['One1', 'Two1', 'Three1'];
// these variables are declared in all pages
// directive variables,
vm.date = {
date: new Date(),
dateOptions: {
formatYear: 'yy',
startingDay: 1
},
format: 'dd-MMMM-yyyy',
opened: false
};
vm.open = function($event) {
vm.date.opened = true;
};
// dataservice
vm.data = []; // the structure can be different but still similar enough
vm.update = function() {
vm.data = pageFactory.get(vm.service);
}
//default call
vm.update();
})
В основном я переместил всю логику, я мог, на фабрики и директивы. Но теперь в каждом контроллере, который использует определенную директиву, мне нужно, например, поле, которое сохраняет значение, которое изменяет директива. И это настройки. Позже мне нужно схожее поле, чтобы хранить данные, поступающие из службы данных, а сам вызов (метод) тот же.
Это приводит к большому количеству повторений.
Графически я вижу, что текущий пример выглядит следующим образом:
Хотя я считаю, что правильный дизайн должен выглядеть примерно так:
Я попытался найти какое-то решение здесь, но, похоже, никто не подтвердил. Что я нашел:
- Структура контроллера DRY DRYHYJJJJJ, предлагая я передать $scope или vm и украсить его дополнительными методами и полями. Но многие источники говорят, что это грязное решение.
- Каков рекомендуемый способ расширения контроллеров AngularJS? с помощью angular.extend, но это имеет проблемы при использовании синтаксиса
controller as
. - И затем я нашел также ответ (в ссылке выше):
Вы не расширяете контроллеры. Если они выполняют одни и те же основные функции, то эти функции необходимо перенести в службу. Эта служба может быть введена в ваши контроллеры.
И даже когда я это сделал, все еще много повторений. Или так оно и должно быть? Как и John Papa sais (http://www.johnpapa.net/angular-app-structuring-guidelines/):
Попробуйте остаться сухим (не повторяйте себя) или T-DRY
Вы столкнулись с подобной проблемой? Каковы варианты?