(function() { 'use strict'; angular.module("app") .directive('myDirective', [getmyDirective]); function getmyDirective() { try { var directiveDefinitionObject = { template: '<dir class="myDirective" ></dir>', replace: true, transclude: false, restrict: 'AE', scope: false, controller: function($scope, $element, $attrs) { $scope.$watch(function() { return document.documentElement.clientWidth; }, function(newValue, oldValue) { SetSize(); } ); function SetSize() { $scope.width = $element.width(); } }, compile: function compile(tElement, tAttrs, transclude) { return { pre: function preLink(scope, iElement, iAttrs, controller) {}, post: function postLink(scope, iElement, iAttrs, controller) { setTimeout(function() { scope.SetSize(); }, 1000); } } }, } return directiveDefinitionObject; } catch (e) { console.log(e); } } })(); 

I need to get the width of the block occupied by the $ scope.width directive. In the block properties, the width is 100% of the parent block.

Initially, after downloading the site directive is missing on the page. After loading, it has the display: hidden property (located under the spoiler).

As can be seen from the code, the width is measured as late as possible, 1 second after the compile postlink is triggered. However, the measurement result is $ scope.width = 100.

When the window is resized, after the directive has become visible,

 $scope.$watch(function() { return document.documentElement.clientWidth; }) 

measuring $ scope.width gives real results.

Question: What are the $ element events that $ watch could be hung to track the directive's actual width? Where can I read it? The decision to hang events on $ ('. MyDirective') is not appropriate, the directive is used repeatedly, the sizes of elements are different.

Passing an external parameter is also not suitable. The width of the element must be determined by the directive itself.

Example:

 var app = angular.module('myApp', []); app.controller('personCtrl', function($scope) { $scope.isOpen = false; }); app.directive('myDirective', [ getmyDirective]); function getmyDirective(){ var directiveDefinitionObject = { template: '<dir class="myDirective" ><dir ng-style="dstyle[size]">window1 {{width}}</dir><dir ng-style="dstyle[size]">window2 {{size}}</dir></dir>', replace: true, transclude:false, restrict: 'AE', scope: false, controller: function($scope, $element, $attrs ) { $scope.$watch(function() { return document.documentElement.clientWidth; }, function(newValue, oldValue) { SetSize(); } ); $scope.SetSize = SetSize; $scope.dstyle = [ { 'width': '25%' , 'float': 'left'}, { 'width': '100%' } ]; function SetSize(){ $scope.width = // 150; $element.width() ; $scope.size= ($scope.width > 200 )? 0: 1; } }, compile: function compile(tElement, tAttrs, transclude) { return { pre: function preLink(scope, iElement, iAttrs, controller) {}, post: function postLink(scope, iElement, iAttrs, controller) { setTimeout(function(){ scope.SetSize(); },1000); } } }, } return directiveDefinitionObject; } 
 .container { width: 100vw} .inside {width: 100%} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <!DOCTYPE html> <html> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> <body> <div ng-app="myApp" ng-controller="personCtrl"> <button ng-click="isOpen=!isOpen" >Open</button> <div ng-if="isOpen" class="container"> <div data-my-directive class="inside"></div> </div> </div> </body> </html> 

  • why body directives in try...catch ? - Grundy
  • $element is a jqLite object, its events are the same as those of a jQuery Object, what side is there a $watch that is in $scope ? - Grundy
  • try ... catch - just in case, it doesn't matter. The project is still in development and it is more convenient to catch errors. - Dolalex
  • without an example, it is absolutely incomprehensible what this directive does and what the problem is, which is unclear how you are trying to solve it - Grundy
  • It is necessary to start the setSize function at the moment when the element will have a specific width. A call to $ watch $ element.width () causes an error, because $ element doesn't exist at certain times - Dolalex

1 answer 1

From the conversation with @Grundy a solution came: The problem was that the directive hidden by jQuery did not have its own width. Therefore, the “revitalization” of the directive should be imposed not on its own, but on the jQuery element. In this case, the accordion was used. The accordion panel was superimposed on the ng-click event that calls apply (I’m not going to describe exactly how I’m applying, because I’m not doing it the best way) with a short (100ms) time delay for jQuery to open the item and ask it width.