2

How can I send an object back from a directive into the parent controller?

I've defined the following directive:

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'
  };
});

... which I call in the following way:

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

... with the following template:

<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>

An ng-click on the li within a list should send the selected obj back the parent controller. The above code calls that parent controller's function, but the object I'm trying to pass comes in as undefined.

I read through the following question: calling method of parent controller from a directive in AngularJS - which I think is trying to do the same thing, but I can't see what I'm doing different than the answer (or my interpretation of it).

How can I the obj coming from the directive's template passed back up to the parent controller?

UPDATE: Here is a JSFiddle: http://jsfiddle.net/EvilClosetMonkey/7GMEG/

When you click on the bulleted values the console should spit out the object.

Community
  • 1
  • 1
Nicholas Pappas
  • 10,439
  • 12
  • 54
  • 87

2 Answers2

2

Change the type of binding from one-way to two-way (& to = in the isolate scope attributes object).

FIDDLE

When you use =, the object (function here) is passed by reference, so you just pass it by name (rather than as a function call like you had before). Then you can invoke it and all is well.

But when you use &, what angular does is wrap what you send in an eval and returns a function wrapping that. So your function that you called in each repetition of the li element would have been something like this:

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

And that's why you would get "whatever" logged, no matter what you pass as obj.


NOTE: Since you use a nested ngRepeat, each li element is 2 child scopes under the controller scope. Calling $parent.$parent.selectObject(obj) would also work as a result. You shouldn't do this and it doesn't really pertain to your question, just a friendly reminder as that kind of thing is brought up a lot on angular SO questions.

Mosho
  • 7,099
  • 3
  • 34
  • 51
  • Many thanks for solution and extra information, it absolutely helped me see what I was not understanding about `&` vs `=`. +2, if I had the extra! :) – Nicholas Pappas Jul 08 '14 at 14:55
0

You can pass the value of 'group' that you're getting from your ng-repeat.

<inspector-shared-objects ng-repeat="group in modelSharedObjects" type="group" filter="filterText" on-select="selectObject(group)"></inspector-shared-objects>
Josh
  • 1,362
  • 1
  • 10
  • 6