Отправить объект из директивы в родительский контроллер в AngularJS

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

Я определил следующую директиву:

app.directive('inspectorSharedObjects', function () {
  return {
    restrict: 'E',
    scope: {
      filterText: '=filter',
      type: '=',
      selectObject: '&onSelect'
    },
    controller: function ($scope) {
      $scope.dot = function (tags) {
        return "label-dot-" + tags[0];
      }
    },
    link: function (scope, element, attrs) {

    },
    templateUrl: 'partials/InspectorSharedObjectListPartial.html'
  };
});

... который я вызываю следующим образом:

<inspector-shared-objects ng-repeat="group in modelSharedObjects" type="group" filter="filterText" on-select="selectObject(obj)"></inspector-shared-objects>

... со следующим шаблоном:

<div class="object-group-header" ng-click="isActive = !isActive" ng-class="{active : isActive}">
  <span>{{ type.name }}</span>
  <span ng-if="filterText">({{ filteredList.length }})</span>
  <i class="fa fa-plus-circle"></i>
</div>
<div class="object-group-list" ng-show="isActive">
  <ul>
    <li ng-repeat="obj in filteredList = (type.contents | filter:filterText | orderBy:'name')" ng-class="dot(obj.tags)" ng-click="selectObject(obj)">{{ obj.name }}</li>
  </ul>
</div>

ng-click в li в списке должен отправить выбранный obj обратно родительскому контроллеру. Приведенный выше код вызывает функцию этого родительского контроллера, но объект, который я пытаюсь передать, имеет вид undefined.

Я прочитал следующий вопрос: метод вызова родительского контроллера из директивы в AngularJS, которая, я думаю, пытается сделать то же самое, но я не вижу, что я делаю иначе, чем ответ (или моя интерпретация этого).

Как я могу передать obj из шаблона директивы обратно родительскому контроллеру?

ОБНОВЛЕНИЕ. Вот JSFiddle: http://jsfiddle.net/EvilClosetMonkey/7GMEG/

Когда вы нажимаете на маркированные значения, консоль должна выдать объект.


person Nicholas Pappas    schedule 07.07.2014    source источник
comment
@Mosho, добавлена ​​скрипка.   -  person Nicholas Pappas    schedule 08.07.2014


Ответы (2)


Измените тип привязки с односторонней на двустороннюю (с & на = в объекте атрибутов изолированной области).

FIDDLE

Когда вы используете =, объект (здесь функция) передается по ссылке, поэтому вы просто передаете его по имени (а не как вызов функции, как раньше). Затем вы можете вызвать его, и все в порядке.

Но когда вы используете &, angular оборачивает то, что вы отправляете, в eval и возвращает функцию, обертывающую это. Итак, ваша функция, которую вы вызывали при каждом повторении элемента li, выглядела бы примерно так:

function(obj){
   return $eval('selectObject("whatever")) 
}

И именно поэтому вы будете регистрировать «все, что угодно», независимо от того, что вы передаете как obj.


ПРИМЕЧАНИЕ. Поскольку вы используете вложенный элемент ngRepeat, каждый элемент li является двумя дочерними областями в области действия контроллера. В результате вызов $parent.$parent.selectObject(obj) также сработает. Вы не должны этого делать, и это на самом деле не относится к вашему вопросу, просто дружеское напоминание, поскольку такие вещи часто возникают в угловых SO-вопросах.

person Mosho    schedule 08.07.2014
comment
Большое спасибо за решение и дополнительную информацию, это абсолютно помогло мне понять, чего я не понимал в отношении & и =. +2, если бы у меня было лишнее! :) - person Nicholas Pappas; 08.07.2014

Вы можете передать значение «группы», которое вы получаете от своего ng-repeat.

<inspector-shared-objects ng-repeat="group in modelSharedObjects" type="group" filter="filterText" on-select="selectObject(group)"></inspector-shared-objects>
person Josh    schedule 07.07.2014
comment
Это возвращает категорию 1, категорию 2 и т. д., а не конкретный элемент, на который нажимает пользователь. - person Nicholas Pappas; 08.07.2014