From 78fb5b5d188f1d0f5c4bcbe075ffe5a6c2c7bbe9 Mon Sep 17 00:00:00 2001 From: Hannes Widmoser Date: Fri, 22 Apr 2016 13:09:12 +0200 Subject: [PATCH 1/5] feat(avoidApply): Avoid calling $apply to not affect an application's performance --- src/ui-layout.js | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/ui-layout.js b/src/ui-layout.js index 223b591..a1078be 100644 --- a/src/ui-layout.js +++ b/src/ui-layout.js @@ -128,7 +128,7 @@ angular.module('ui.layout', []) debounceEvent = $timeout(function() { $scope.$broadcast('ui.layout.resize', beforeContainer, afterContainer); debounceEvent = null; - }, 50); + }, 50, false); } } } @@ -835,13 +835,17 @@ angular.module('ui.layout', []) e.stopPropagation(); htmlElement.on('mousemove touchmove', function(event) { - scope.$apply(angular.bind(ctrl, ctrl.mouseMoveHandler, event)); + ctrl.mouseMoveHandler(event); + var splitbarIndex = ctrl.containers.indexOf(scope.splitbar); + ctrl.containers[splitbarIndex - 1].update(); + ctrl.containers[splitbarIndex + 1].update(); + scope.$digest(); }); return false; }); htmlElement.on('mouseup touchend', function(event) { - scope.$apply(angular.bind(ctrl, ctrl.mouseUpHandler, event)); + ctrl.mouseUpHandler(event); htmlElement.off('mousemove touchmove'); }); @@ -929,8 +933,12 @@ angular.module('ui.layout', []) } }); + scope.container.updateSize = function() { + element.css(ctrl.sizeProperties.sizeProperty, scope.container.size + 'px'); + } + scope.$watch('container.size', function(newValue) { - element.css(ctrl.sizeProperties.sizeProperty, newValue + 'px'); + scope.container.updateSize(); if(newValue === 0) { element.addClass('ui-layout-hidden'); } else { @@ -938,8 +946,17 @@ angular.module('ui.layout', []) } }); + scope.container.updatePosition = function() { + element.css(ctrl.sizeProperties.flowProperty, scope.container[ctrl.sizeProperties.flowProperty] + 'px'); + } + + scope.container.update = function() { + scope.container.updatePosition(); + scope.container.updateSize(); + } + scope.$watch('container.' + ctrl.sizeProperties.flowProperty, function(newValue) { - element.css(ctrl.sizeProperties.flowProperty, newValue + 'px'); + scope.container.updatePosition(); }); //TODO: add ability to disable auto-adding a splitbar after the container From afa9d53095f98d7b86dc0f909828167a3bdecbd7 Mon Sep 17 00:00:00 2001 From: Hannes Widmoser Date: Fri, 22 Apr 2016 14:50:58 +0200 Subject: [PATCH 2/5] feature(avoidApply): Manage splitbar position manually --- src/ui-layout.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/ui-layout.js b/src/ui-layout.js index a1078be..80d87a3 100644 --- a/src/ui-layout.js +++ b/src/ui-layout.js @@ -839,7 +839,7 @@ angular.module('ui.layout', []) var splitbarIndex = ctrl.containers.indexOf(scope.splitbar); ctrl.containers[splitbarIndex - 1].update(); ctrl.containers[splitbarIndex + 1].update(); - scope.$digest(); + scope.splitbar.updatePosition(); }); return false; }); @@ -853,9 +853,11 @@ angular.module('ui.layout', []) element.css(ctrl.sizeProperties.sizeProperty, newValue + 'px'); }); - scope.$watch('splitbar.' + ctrl.sizeProperties.flowProperty, function(newValue) { - element.css(ctrl.sizeProperties.flowProperty, newValue + 'px'); - }); + scope.splitbar.updatePosition = function() { + element.css(ctrl.sizeProperties.flowProperty, scope.splitbar[ctrl.sizeProperties.flowProperty] + 'px'); + }; + + scope.$watch('splitbar.' + ctrl.sizeProperties.flowProperty, scope.splitbar.updatePosition); scope.$on('$destroy', function() { htmlElement.off('mouseup touchend mousemove touchmove'); @@ -935,7 +937,7 @@ angular.module('ui.layout', []) scope.container.updateSize = function() { element.css(ctrl.sizeProperties.sizeProperty, scope.container.size + 'px'); - } + }; scope.$watch('container.size', function(newValue) { scope.container.updateSize(); @@ -948,16 +950,14 @@ angular.module('ui.layout', []) scope.container.updatePosition = function() { element.css(ctrl.sizeProperties.flowProperty, scope.container[ctrl.sizeProperties.flowProperty] + 'px'); - } + }; scope.container.update = function() { scope.container.updatePosition(); scope.container.updateSize(); - } + }; - scope.$watch('container.' + ctrl.sizeProperties.flowProperty, function(newValue) { - scope.container.updatePosition(); - }); + scope.$watch('container.' + ctrl.sizeProperties.flowProperty, scope.container.updatePosition); //TODO: add ability to disable auto-adding a splitbar after the container var parent = element.parent(); From e6ab9fa22491acebc981cf1a0b307d2e50a6dfa4 Mon Sep 17 00:00:00 2001 From: Hannes Widmoser Date: Fri, 22 Apr 2016 15:07:57 +0200 Subject: [PATCH 3/5] feat(avoidApply): Trigger resizing in the animation frame --- src/ui-layout.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ui-layout.js b/src/ui-layout.js index 80d87a3..380e5fd 100644 --- a/src/ui-layout.js +++ b/src/ui-layout.js @@ -123,6 +123,10 @@ angular.module('ui.layout', []) // move the splitbar ctrl.movingSplitbar[position] = newPosition; + ctrl.movingSplitbar.updatePosition(); + beforeContainer.update(); + afterContainer.update(); + // broadcast an event that resize happened (debounced to 50ms) if(debounceEvent) $timeout.cancel(debounceEvent); debounceEvent = $timeout(function() { @@ -132,7 +136,6 @@ angular.module('ui.layout', []) } } } - //Enable a new animation frame animationFrameRequested = null; } @@ -836,10 +839,6 @@ angular.module('ui.layout', []) htmlElement.on('mousemove touchmove', function(event) { ctrl.mouseMoveHandler(event); - var splitbarIndex = ctrl.containers.indexOf(scope.splitbar); - ctrl.containers[splitbarIndex - 1].update(); - ctrl.containers[splitbarIndex + 1].update(); - scope.splitbar.updatePosition(); }); return false; }); From 457494ed4de87c356b6afffb3cd447366d7dc18d Mon Sep 17 00:00:00 2001 From: Hannes Widmoser Date: Fri, 22 Apr 2016 16:07:42 +0200 Subject: [PATCH 4/5] feat(avoidApply): Replace $evalAsync when window is resized --- src/ui-layout.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ui-layout.js b/src/ui-layout.js index 380e5fd..4d1039b 100644 --- a/src/ui-layout.js +++ b/src/ui-layout.js @@ -656,8 +656,9 @@ angular.module('ui.layout', []) }); function onResize() { - scope.$evalAsync(function() { - ctrl.calculate(); + ctrl.calculate(); + ctrl.containers.forEach(function(c) { + c.update(); }); } @@ -856,6 +857,10 @@ angular.module('ui.layout', []) element.css(ctrl.sizeProperties.flowProperty, scope.splitbar[ctrl.sizeProperties.flowProperty] + 'px'); }; + scope.splitbar.update = function() { + scope.splitbar.updatePosition(); + }; + scope.$watch('splitbar.' + ctrl.sizeProperties.flowProperty, scope.splitbar.updatePosition); scope.$on('$destroy', function() { From 41f0cc09dd375a4b762106d6c1c06003c3400ce1 Mon Sep 17 00:00:00 2001 From: Hannes Widmoser Date: Wed, 25 May 2016 17:04:50 +0200 Subject: [PATCH 5/5] feat(avoidApply): Trigger a local digest before the broadcast This is needed in order to first let child ui-layouts update their size before listeners are informed --- src/ui-layout.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui-layout.js b/src/ui-layout.js index 4d1039b..a9fda27 100644 --- a/src/ui-layout.js +++ b/src/ui-layout.js @@ -130,6 +130,7 @@ angular.module('ui.layout', []) // broadcast an event that resize happened (debounced to 50ms) if(debounceEvent) $timeout.cancel(debounceEvent); debounceEvent = $timeout(function() { + $scope.$digest(); $scope.$broadcast('ui.layout.resize', beforeContainer, afterContainer); debounceEvent = null; }, 50, false);