Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it ok watch the scope inside a custom directive?

I'm trying to write a directive to create a map component so I can write something like:

<map></map>

Now the directive looks like this:

angular.module('myApp')
  .directive('map', function (GoogleMaps) {
    return {
      restrict: 'E',
      link: function(scope, element, attrs) {
        scope.$watch('selectedCenter', function() {
          renderMap(scope.selectedCenter.location.latitude, scope.selectedCenter.location.longitude, attrs.zoom?parseInt(attrs.zoom):17);
        });

      function renderMap(latitude, longitude, zoom){
          GoogleMaps.setCenter(latitude, longitude);
          GoogleMaps.setZoom(zoom);
          GoogleMaps.render(element[0]);
      }
    }
  };
});

The problem is that 'watch' inside the directive doesn't looks very well thinking in the reusability of the component. So I guess the best thing is being able to do something like:

<map ng-model="selectedCenter.location"></map>

But I don't know if it's even a good thing using angular directives inside custom directives or how can I get the object indicated in the ng-model attribute in the custom-directive's link function.

like image 951
Henry Morgan Avatar asked Sep 14 '13 10:09

Henry Morgan


2 Answers

You will need to do something like that

angular.module('myApp')
  .directive('map', function (GoogleMaps) {
    return {
      restrict: 'E',
      scope: {
        ngModel: '=' // set up bi-directional binding between a local scope property and the parent scope property 
      },

as of now you could safely watch your scope.ngModel and when ever the relevant value will be changed outside the directive you will be notified.

Please note that adding the scope property to our directive will create a new isolated scope.

You can refer to the angular doc around directive here and especially the section "Directive Definition Object" for more details around the scope property.

Finally you could also use this tutorial where you will find all the material to achieve a directive with two way communication form your app to the directive and opposite.

like image 64
Nicolas ABRIC Avatar answered Oct 06 '22 01:10

Nicolas ABRIC


Without scope declaration in directive:

html

<map ng-model="selectedCenter"></map>

directive

app.directive('map', function() {
    return {
        restrict: 'E',
        require: 'ngModel',
        link: function(scope, el, attrs) {              
            scope.$watch(attrs.ngModel, function(newValue) {
                console.log("Changed to " + newValue);
            });                 
        }
    };
});
like image 37
Frankey Avatar answered Oct 06 '22 00:10

Frankey