Как я могу надежно получить область действия контроллера в директиве?

Скажем, у меня есть директива, которая просто выводит идентификатор области видимости.

.directive('myCustomer', function() {
  return {
    template: 'directive scope {{$id}}',
    link: function(scope, el, attrs) {
      //console.log('controller scope', 'HOW?');
    }
  };
});

Случай 1:
используется в контроллере, как обычно. Он выводит 003 как для контроллера, так и для директивы.

<div ng-controller="Ctrl">
  controller scope : {{$id}}
  <div my-customer></div>
</div>

демо: http://plnkr.co/edit/3UyDwk?p=preview

Случай 2.
Затем я использовал ту же директиву в контроллере, что и следующая, в ng-include и ng-repeat. Следующее выводит идентификаторы областей, 003, 004, 005… и так далее.

<div ng-controller="Ctrl">
  controller scope : {{$id}}
  <div ng-include="'ng-repeat.html'"></div>
</div>

демо: http://plnkr.co/edit/6vMpCt?p=preview

Я понимаю, что ng-include и ng-repeat создают свою собственную область.

Вопрос:
Мой вопрос: "Как я могу надежно получить область действия контроллера в директиве?"

Из приведенного выше случая 1 и случая 2 я хочу получить область «003» в директиве с тем же кодом.

Я могу использовать scope для случая 1,
но для случая 2 мне нужно использовать scope.$parent.$parent
и если я использую только ng-repeat, мне нужно использовать scope.$parent
Что, если я использую его внутри ng-include и нг-включить? scope.$parent.$parent.$parent…?

Я искал код типа scope.controllerScope(), которого не существует.

Мой вариант использования - вызвать функцию в контроллере из директивы без использования изолированной области.

Надеюсь, мой вопрос понятен.


person allenhwkim    schedule 22.01.2014    source источник
comment
Поскольку область действия контроллера является родительской для вашей директивы, любая функция, установленная на вашем контроллере, доступна (через наследование) для вашей директивы, если она не была заменена. Итак, если все, что вам нужно, это вызвать функцию в области контроллера, вы можете сделать это без прямого доступа к ее области: обновил скрипт.   -  person KayakDave    schedule 22.01.2014
comment
@KayakDave, спасибо. это так просто.   -  person allenhwkim    schedule 24.01.2014


Ответы (1)


Я пробовал некоторые методы, но это лучшее решение, которое я нашел:

Вот плункер: http://plnkr.co/edit/bA6jww?p=preview

Мы можем изменить все контроллеры, украсив $controllerProvider:

app.config(function($provide){
  $provide.decorator('$controller', ['$delegate', function($delegate) {
    return function (expression, locals) {
      if (expression != angular.noop) {
        locals.$scope.$controllerId = locals.$scope.$id;
      }
      return $delegate(expression,locals)
    }
  }]); 
})

Теперь мы можем связать его с данными через цепочку прототипов:

{{$controllerId}}

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

person Ilan Frumer    schedule 22.01.2014
comment
Спасибо. Это будет полезно, когда я создам директиву для собственного использования. Еще одно предостережение заключается в том, что это поведение не контролируется, если я создаю общедоступный модуль, т. Е. angularjs-google-maps. - person allenhwkim; 23.01.2014
comment
Пожалуйста, опишите ваш вариант использования. У меня есть больше способов, но это зависит от того, что вам нужно именно - person Ilan Frumer; 24.01.2014