2

I am creating a web app that has multiple dialog windows set up by ng-repeat'ing a directive, <make-dialog>. Information specific to each dialog (width, height, position, etc), is stored in an array in the controller and passed into the directive as a scope variable.

Now, I would like to add a boolean scope variable that can be accessed and modified by all the dialog windows. So when you click the "+" button in any of the dialogs, the scope variable changes to "true", and all the other dialogs recognize that that change has been made.

Here is a sketch of the code I have tried:

Controller:

angular.module('root', [])
.controller('index', ['$scope', function($scope){
$scope.dialogs = [
  {
    minimized: false,
    maximized: false,
    width: 200,
    height: 300,
    top: 5,
    left: 5,
    zindex: 1,
    template: 'experiment-dialog.html'
  },

  {
    minimized: false,
    maximized: false,
    width: 200,
    height: 250,
    top: 257,
    left: 238,
    zindex: 0,
    template: 'other-dialog.html'
  }];

$scope.bool = false; //The variable I want to be able to access and change

}]);

Directive:

.directive('makeDialog', function($document) {
return {
    restrict: 'E',
    scope: {
        model: '=',
        dialogs: '=',
        bool: '='
    },
    template: "<button ng-click='maximize()> + </button>'",
    link: function(scope, element, attrs) {

        scope.maximize = function() {
            scope.bool = true;
        }
    }
   }
 });

index.html:

 <html>
  <body ng-app='root' ng-controller='index'>
    <div id='container'>
      <div ng-repeat='dialog in dialogs|filter:{minimized:false}'>
        {{bool}}
        <make-dialog model='dialog' dialogs='dialogs' bool='bool'></make-dialog> 
      </div>
    </div>
  </body>
 </html>

This displays on the screen two buttons and the words "false false". But when I click one of the "+" buttons, only one of the "false" values changes to true. So this variable is not global, but is somehow only seen by one dialog. Is there any way to fix this, so that clicking on one button will make both dialogs realize that the variable is now true?

user112233
  • 91
  • 9
  • My full plunker can be found here: http://plnkr.co/edit/ABQd8ZGVGeRlNWI6xIGy?p=preview, it has rather more code than the simplified version I put above, but feel free to take a look if you think it would help. – user112233 Aug 03 '15 at 16:18
  • 1
    try with an object reference instead of a primitive. bool='my.bool' – Liviu T. Aug 03 '15 at 16:20
  • 1
    Your demo seems not demonstrating your problem. I clicked `+` but nothing happens – Joy Aug 03 '15 at 16:21
  • @Joy try again? It works when I follow the plunkr link. Look at the "false"'s listed in the top left. – user112233 Aug 03 '15 at 16:25
  • 1
    Because `ng-repeat` creates a child scope, each dialog writes to a `bool` property of the child scope, rather than the global. To get to the global, make sure that you use an object (i.e. ViewModel) - or simply put, make sure that you have a `.` dot in the bound variable. For more info, see [this answer](http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs) – New Dev Aug 03 '15 at 16:31

1 Answers1

1

Check working demo: Plunker

Your problem is that you bind the model to some primitive variable inside the ng-repeat:

The ngRepeat directive instantiates a template once per item from a collection. Each template instance gets its own scope

So, use some object to perform the two-way binding.

Joy
  • 9,430
  • 11
  • 44
  • 95