Как в директиве получить контроллер в который она обернута?

Сначала начал задавать более общий вопрос, но потом понял что Вызван он незнанием того, как получить контроллер, в который обернута директива.
<div ng-controller="SomeControeller as someControeller">
	<some ng-click="someControeller.run()">####</some>
</div>

function SomeController(){
	this.run = function(){
		console.log('SomeController');
	}
}

function someDirective(){
	return {
		controller: 'SomeControeller',
		link: function($scope, iElm, iAttrs, controller) {
			console.log(controller);
			controller.run = function(){
				console.log('directive');
			}
		}
	};
}

var app = angular.module('app', []);
app.controller('SomeControeller', [SomeController]);
app.directive('some', [someDirective]);
angular.bootstrap(document, ['app']);

Вот только сейчас узнал, что контроллер в link лишь ещё один экземпляр контроллера,
а не тот во что обернута директива. Нагуглить сам не смог, так как не понимаю что спрашивать.
По этому остается спросить только Вас - как получить нужный контроллер или если его и не нужно получать по идеологии, то почему?

UPD: 0.0.0
А вопрос этот возник тогда, когда я попытался в директиве вызвать обработчик события клика. Получилось что чтобы вызвать обработчик, то он должен быть либо в области видимости контроллера, либо в скопе. Второй вариант я сразу отбросил, так как если вешать хендлеры на скопу, тогда вообще дался контроллер да ещё в директиве.. Вот и остался я с вариантом в котором контролер хандлеры содержит, но не понимаю, как его приспособить.
  • Вопрос задан
  • 987 просмотров
Решения вопроса 1
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
или если его и не нужно получать по идеологии, то почему?

потому что это создает зависимость директивы от контекста, в котором она используется. Проследите логику

1) работа директивы требует того что бы она была обернута в SomeControeller на уровень выше.
2) директива становится частью SomeControeller, или если быть точным, куска view которым управляет SomeControeller.
3) нет смысла в директиве, так как мы не можем более реюзать ее в другом месте
4) если директива зависит от контроллера SomeControeller, почему бы не вынести из SomeControeller то что нужно директиве в ее собственный контроллер?

как-то так. Все взаимодействие с директивой должно происходить либо через контроллеры директив (параметр require директивы), либо через атрибуты (изолированный scope, bindToController в angular 1.4). И уж тем более странно желание подменять методы контроллера из link.

updated

короче суть в непонимании того что есть директива как я понимаю. Директива - самодостаточная единица (самостоятельное маленькое MVC приложение). По хорошему она может зависеть только от других директив, но ей глубоко должно быть плевать где именно и как ее используют. Она выполняет свой маленький кусочек логики. Некоторые директивы выступают в роли фасадов, инкапсулируя в себе и упрощая работу с множеством директив.

Далее, по поводу обработчиков - яркий пример директива ng-click. Эта директива выглядит как-то так:

function myNgClick() {
    return {
        restrict: 'A',
        scope: {
            callback: "&myNgClick"
        },
        link: function (scope, el) {
            el.bind('click', function (e) {
                scope.$apply(function () {
                     scope.callback({$event: e});
                });
            });
        }
    }
}


Как мы видим на этом примере, у нас есть директива, чья основная задача - вызвать что-то по клику на элемент. И все. Через эту директиву мы скажем можем дернуть метод контроллера другой директивы. В этом проявляется сила ангуляра, мы можем проводить декомпозицию элементов интерфейса настолько глубоко насколько мы вообще хотим. делать крайне изолированные, маленькие и простые директивы, которые очень легко покрыть тестами и легко использовать.

link директивы нужен ТОЛЬКО для того что бы связать DOM и логику. То есть в 99% случаев в директиве будет только link или только контроллер. Оба - это уже стремно, в этом случае лучше вынести ту логику которую хочется запихнуть в link в отдельную директиву.

контроллер (мы сейчас отойдем чуть чуть от MVC только ради того что бы упростить все) реализует всю логику (или делегирует модели). Вся логика не относящаяся к DOM а например относящаяся к обработке данных должна быть вынесена в контроллер.

Пара слов по поводу ng-controller. Это так же директива, которая позволяет привязать к элементу какой-то контроллер. Эта штука по сути (как и ng-include в принципе) нужна только для ускорения разработки и упрощения. В целом же приложение на angular стоит воспринимать как HMVC приложение, состоящее исключительно из деревьев директив. Первый шаг на пути к web-components (по сути ангуляровские директивы послужили неплохим глотком вдохновения).

Как-то так.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы