4

so this is how it looks like, and here is the Plunker

parent scope 
   ng-repeat
       directive

in the directive there is an attribute is bi-directional binding with a variable in parent scope.

But this doesn't work as I wanted.(But I can understand why it doesn't work)

The reason is ngRepeat will create it's own scope, so once the variable is changed in directive, Angular add a variable in ngRepeat, but it leave the variable in parent unchanged.

I can do something like scope.$parent.$parent.variable to change the variable, but it is kinda not the idea in Angular.

How should I do ?

Moreover, if I change the repeated item in the items collection, the item can't be changed.

Because of the same reason above.

maxisam
  • 21,975
  • 9
  • 75
  • 84
  • 2
    In case it helps try binding to non-primitive types (like an object). The binding should still work as expected even though there are child scopes being created unless you are binding to primitives. See [this post](http://stackoverflow.com/a/12978044/1207991) for more info on it. – Gloopy Oct 30 '12 at 22:45
  • nope, that is not what I asked. Thanks anyway. – maxisam Oct 30 '12 at 22:47
  • an $emit might do it but I don't like that answer.. feel like there's something better out there: http://docs.angularjs.org/api/ng.$rootScope.Scope#$emit – Roy Truelove Oct 31 '12 at 02:35
  • 1
    bubble the event, this works but I do feel the same with you – maxisam Oct 31 '12 at 03:13
  • Thanks @Gloopy, in turns out you are right to the point. I should read that post more carefully. – maxisam Oct 31 '12 at 14:20

1 Answers1

5

EDIT (again): It looks like the issue is you need to have reference types in your array, such as objects or arrays.

Gloopy was exactly right in the comments. The bi-directional binding wasn't working because it seems like Angular was creating copies of your primitives types (strings, numbers, etc) between the second scope pairing. So... when you have a nesting of bi-directionally bound primitive types between two scopes it's fine because it uses one instance, but when you nest it more than one deep, it creates a copy of the primitive and you're no longer updating the same instance.

Here's a new demo

app.controller('MainCtrl', function($scope) {
  $scope.items = [
    { text: 'apples' },
    { text: 'bananas' },
    { text: 'oranges' }
  ];
  $scope.addItem = function(){
    $scope.items.push({ text: 'test' });
  };
});

app.directive('test', function(){
  return {
    restrict: 'E',
    scope: {
      foo: '=foo'
    },
    template: '<div>{{foo}} <a ng-click="bar()">bar</a></div>',
    controller: function($scope){ 
      $scope.bar = function() {
        $scope.foo += '!';
      };
    }    
  };
});
Ben Lesh
  • 107,825
  • 47
  • 247
  • 232
  • Thanks for response :) http://plnkr.co/edit/HVy0QV I used your example, but the parent doesn't change. I think `scope.$parent` is the scope created by ngRepeat – maxisam Oct 31 '12 at 04:05
  • I think I've figured it out. Gloopy's comment above was exactly right. You need to bind to references types. – Ben Lesh Oct 31 '12 at 13:46
  • 1
    Thank you ! I also found some discussions about this https://groups.google.com/forum/#!searchin/angular/copy$20reference$20primitives$20/angular/VD77QR1J6uQ/LN1YDBTJc2gJ – maxisam Oct 31 '12 at 17:09
  • Once again sir @blesh, you saved my time. – mrsus Mar 19 '14 at 08:05