Search code examples
cssangularjsdata-bindingng-style

How to bind DOM property in directive


Given this example:

var SomeApp = angular.module('SomeApp', [])
  .controller('SomeController', function($scope){
    $scope.items = [0,1,2,3]
  })
  .directive('gridResize', function(){
    return {
      scope: true,
      link: function(scope, elem) {
        scope.gridResize = {
          width: $(elem).width(),
          height: $(elem).height()
        };
      }
    }
  })
.parent {
  width: 80%;
  position: relative;
  left: 50%;
  transform: translateX(-50%);
  border: 1px solid red;
}
.parent > * {
  background-color: rgba(0,0,0,.14);
  margin-bottom: 1px;
  padding: 20px;
  box-sizing: border-box;
}
.parent > *:last-child {
  margin-bottom: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="SomeApp">
  <div class="parent" ng-controller="SomeController" grid-resize>
    <div ng-style="{'min-height':($parent.gridResize.width/8) + 'px'}" 
         ng-repeat="item in items"
         >
      height: {{$parent.gridResize.height}} | width: {{$parent.gridResize.width}}
    </div>
  </div>
</div>

Can anyone tell me how I could bind the height and width of the grid-resize directive to the DOM element? I want the angular properties to change when the DOM element changes.


Solution

  • In your directive use the window "resize" event to update the sizes on the scope:

    var SomeApp = angular.module('SomeApp', [])
      .controller('SomeController', function($scope){
        $scope.items = [0,1,2,3]
      })
      .directive('gridResize', function(){
        return {
          scope: false,
          link: function(scope, elem) {
            scope.gridResize = {
              width: $(elem).width(),
              height: $(elem).height()
            };
            angular.element(window).on('resize', function(e) {
               scope.gridResize = {
                  width: $(elem).width(),
                  height: $(elem).height()
               };
               scope.$apply();
            });
          }
        }
      })
    

    Also notice that I changed the directive's scope to 'false'. You already have a scope on that element created by the ng-controller directive.