sandip
sandip

Reputation: 3289

Angular directive scope sharing between two directive

I am working on a project where I have one controller and two directives and I need to share the scope between them all, I have created plnkr here.

The code structure is as following:

Main Controller

--Drawable Directive

----Draw-rectangle Directive

In the Main ctrl there is one object rois on scope which I am to Drawable and Draw-rectangle directive. and on click of drawable it updates to scope of Main controller but when I click on the draw-rectangle directive it's not updating the scope.

I want to all (3) scopes to be synced using two way data binding.

It seems conceptually correct but why its not updating the scope from Draw-rectangle Directive?

Thanks in advance!

Upvotes: 1

Views: 535

Answers (3)

Bruno João
Bruno João

Reputation: 5535

When you click "draw-rectangle" your are also clicking "drawable" because "draw-rectangle" is inside "drawable". You must stop propagation from "draw-rectangle" to "drawable" using event.preventDefault(); as folow:

var app = angular.module('myApp', []);

app.controller('MainCtrl', function($scope) {
  $scope.rois = [{
    name: 'Jack',
    city: 'pune'
  }, {
    name: 'Tony',
    city: 'Mumbai'
  }];
  $scope.test = "Test";
});

app.directive('drawable', [
  function() {
    return {
      restrict: "EA",
      link: function(scope, element, attrs) {
        element.on('click', function(event) {
          event.preventDefault();
          scope.rois = [{
            name: 'Stark',
            city: 'pune'
          }, {
            name: 'Inc',
            city: 'Mumbai'
          }];
          scope.$apply();
          console.log(scope.rois);
        });
      }
    };
  }
]);

app.directive('drawRectangle', [
  function() {
    return {
      restrict: "EA",
      link: function(scope, element, attrs) {
        element.on('click', function(event) {
          event.stopPropagation(); // STOP PROPAGATION
          event.preventDefault();
          scope.rois = [{
            name: 'Meuk',
            city: 'pune'
          }, {
            name: 'Tony',
            city: 'Mumbai'
          }];
          scope.$apply();
          console.log(scope.rois);
        });
      }
    };
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="myApp" ng-controller='MainCtrl' style='width: 400px;height: 400px;border: 1px solid red;'>
  <div drawable rois="rois" style='width: 300px;height: 300px;border: 1px solid red;'>
    <div draw-rectangle rois="rois" style='width: 200px;height: 200px;border: 1px solid red;'>
      <button type="button" style='margin: 20px; border: 1px solid red;'>Click me!</button>
    </div>
  </div>
  <br>
  <br>{{rois | json}}
</div>

Upvotes: 1

Josh Lin
Josh Lin

Reputation: 2437

u need to stop bubble up the event, because when rect directive clicked, drawable also trigger click! use event.stopPropagation()

var app = angular.module('myApp');
app.directive('drawable', ['$document',
  function($document) {
    return {
      restrict: "EA",
      scope: {
        rois: '='
      },
      link: function(scope, element, attrs) {
        console.log(scope.rois);

        element.on('click', function(event) {
          event.stopPropagation();
          scope.rois = [{
            name: 'Stark',
            city: 'pune'
          }, {
            name: 'Inc',
            city: 'Mumbai'
          }];
          scope.$apply();

          console.log(scope.rois);
        });
      }
    };
  }
]);

app.directive('drawRectangle', ['$document',
  function($document) {
    return {
      restrict: "EA",
      scope: {
        rois: '='
      },
      link: function(scope, element, attrs) {
        element.on('click', function(event) {
          event.stopPropagation();
          scope.rois = [{
            name: 'Meuk',
            city: 'pune'
          }, {
            name: 'Tony',
            city: 'Mumbai'
          }];
          scope.$apply();
          console.log(scope.rois);
        });
      }
    };
  }
]);

Upvotes: 1

Vinoth Rajendran
Vinoth Rajendran

Reputation: 1211

You are using isolated scope for two directives. Isolated scope will create a child scope. So, you cannot access "rois" out of the directive's link function. Try after you remove the isolated scope,

 scope: {
    rois: '='
 },

Upvotes: 0

Related Questions