Наряду с элементом Transclude, могу ли я передать его область действия директиве?

В тот момент, когда я почувствовал, что достаточно понял о Transclude, я наткнулся на это утверждение:

Transclude allows us to pass in an entire template, including its scope, to a directive. 
Doing so gives us the opportunity to pass in arbitrary content and arbitrary scope to a directive.

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

Позвольте мне сделать пару шагов назад и объяснить с помощью кода, что я пытаюсь сделать:

Ссылка JSFiddle

Моя директива directive-box, а transclude: true определена в объекте определения директивы (DDO).

Теперь есть дочерний элемент Div, который должен быть включен.

<div ng-controller='TransCtrl'>Inside Transclude Scope : {{name}}</div>

и к нему подключен контроллер TransCtrl.

Теперь я пытаюсь получить доступ к свойству $scope.name, которое является частью TransCtrl, с уровня директивы после определения этого в DDO:

scope: {
        title: '@directiveTitle',
        name: '='
      }

Это возможно ?

Это больше похоже на родительскую область, пытающуюся получить доступ к свойству дочерней области, разрешено ли это в прототипном наследовании JavaScript? Или есть что-то еще, что мне нужно знать??

Если это невозможно, что означает первое утверждение?

Transclude allows us to pass in an entire template, including its scope, to a directive.

ОБНОВЛЕНИЕ 1:

Моя основная задача заключается в том, что контроллер должен оставаться с элементом Transclude, но мы должны иметь возможность передать его область (элемент Transclude) в директиву, а затем директива должна иметь возможность использовать эту область, т. е. name from TransCtrl controller .

<div ng-controller='TransCtrl'>Inside Transclude Scope : {{name}}</div>

Вышеприведенная строка кода должна оставаться как есть.

Я могу быть совершенно неправ в своем вопросе, но, пожалуйста, дайте мне, если это можно сделать.


person BeingSuman    schedule 17.07.2016    source источник
comment
Если какой-либо ответ был полезен, отметьте его как принятый. В противном случае уточните, где требуется дополнительная помощь.   -  person Aron    schedule 17.07.2016


Ответы (2)


Проблема, похоже, связана с тем, как контроллер определяется в ng-transcluded html.

Я сделал это более ясным, используя

  1. конструкция bindToController
  2. использование контроллера на директивном уровне

Обратитесь к этой скрипке для рабочего примера.

controllerAs: "TransCtrl",
bindToController: true

И ваше утверждение «Родительская область пытается получить доступ к свойству дочерней области» неверно, верно? Поскольку мы пытаемся использовать свойство родительской области видимости, т. е. имя внутри дочернего элемента (ng-transcluded content), что возможно при прототипическом наследовании, а не наоборот.

person Aditi    schedule 17.07.2016
comment
спасибо за ваше время, но предоставленная вами альтернатива имеет область действия, перемещенную в Директиву. Пожалуйста, проверьте ОБНОВЛЕНИЕ 1 в вопросе. - person BeingSuman; 18.07.2016

Это отвечает на ваш вопрос: https://jsfiddle.net/marssfa4/4/?

В нем я создал новый контроллер снаружи (фактически заменив функциональность вашего rootScope внутри директивы), и я установил контроллер директивы внутри вашего шаблона контроллера.

Короче говоря, вы можете видеть, что можно включить html вместе с его областью действия даже в директиву с собственной областью действия.

HTML:

<div ng-app='myApp' ng-controller="OutsideScope">
  <h1>{{externalWorld}}</h1>
  <div directive-box directive-title='{{directiveWorld}}' name='name'>
    <div>Inside Transclude Scope : {{name}}</div>
  </div>
</div>

JS (включает обновление 1):

angular.module('myApp', [])
  .directive('directiveBox', function() {
    return {
      restrict: 'EA',
      scope: {
        title: '@directiveTitle',
        name: '='
      },
      transclude: true,
      template: '<div ng-controller="TransCtrl">\
        <h2 class="header">{{ title }}</h2>\
                <div class="dirContent">Directive Element</div>\
                <div>Outside Transclude Scope : {{name}}</div>\
                <div class="content" ng-transclude></div>\
            </div>'
    }
  })
  .controller('TransCtrl', function($scope) {
    $scope.name = 'Transclude World'
  })
  .controller('OutsideScope', function($scope) {
    $scope.name = 'External World'
  })
  .run(function($rootScope) {
    $rootScope.externalWorld = 'External World',
      $rootScope.directiveWorld = 'Here comes directive'
  });

ОБНОВЛЕНИЕ 1: JSFIDDLE

Я восстановил исходные объявления области действия, так как scope: false было ошибкой.

Если я правильно понимаю ваш комментарий, вы хотите оставить контроллер на элементе, который будет включен, но при этом {{name}} внутри этого элемента игнорирует его непосредственный контроллер и использует в качестве контроллера его родительскую область (т.е. директиву).

Причина, по которой я поместил контроллер в директиву шаблона, заключается в том, что это единственный способ ограничить область действия директивы директивой, а не включенными в нее элементами. Если вы явно размещаете контроллер на элементе, то независимо от того, содержится ли он в директиве с другой областью действия, его ближайшая область действия переопределит любую область действия, объявленную в директиве. Другими словами, независимо от того, какова область действия директивы, {{name}} в

<div ng-controller='TransCtrl'>Inside Transclude Scope : {{name}}</div>

всегда будет тем, что $scope.name находится в TransCtrl.

person Aron    schedule 17.07.2016
comment
Спасибо за ваше время. Пожалуйста, проверьте ОБНОВЛЕНИЕ 1, о котором идет речь. Я вижу, как вы полностью удаляете контроллер из элемента Transclude, а это не то, чего я хочу. Другая вещь, которую вы объявили scope:false, scope: { title: '@directiveTitle', name: '=' } Я не знаю, разрешено ли это или как это работает, давая два противоположных объявления области действия в DDO? - person BeingSuman; 18.07.2016
comment
Я обновил ответ в соответствии с моим пониманием вашего вопроса. По сути, у вас не может быть обоих способов: вы не можете явно установить контроллер для элемента и ожидать, что он будет перезаписан его родительской областью. - person Aron; 18.07.2016