如何在调整指令大小时通知我? 我试过了
element[0].onresize = function() {
console.log(element[0].offsetWidth + " " + element[0].offsetHeight);
}
但它没有调用函数
(function() {
'use strict';
// Define the directive on the module.
// Inject the dependencies.
// Point to the directive definition function.
angular.module('app').directive('nvLayout', ['$window', '$compile', layoutDirective]);
function layoutDirective($window, $compile) {
// Usage:
//
// Creates:
//
var directive = {
link: link,
restrict: 'EA',
scope: {
layoutEntries: "=",
selected: "&onSelected"
},
template: "<div></div>",
controller: controller
};
return directive;
function link(scope, element, attrs) {
var elementCol = [];
var onSelectedHandler = scope.selected();
element.on("resize", function () {
console.log("resized.");
});
$(window).on("resize",scope.sizeNotifier);
scope.$on("$destroy", function () {
$(window).off("resize", $scope.sizeNotifier);
});
scope.sizeNotifier = function() {
alert("windows is being resized...");
};
scope.onselected = function(id) {
onSelectedHandler(id);
};
scope.$watch(function () {
return scope.layoutEntries.length;
},
function (value) {
//layout was changed
activateLayout(scope.layoutEntries);
});
function activateLayout(layoutEntries) {
for (var i = 0; i < layoutEntries.length; i++) {
if (elementCol[layoutEntries[i].id]) {
continue;
}
var div = "<nv-single-layout-entry id=slot" + layoutEntries[i].id + " on-selected='onselected' style=\"position:absolute;";
div = div + "top:" + layoutEntries[i].position.top + "%;";
div = div + "left:" + layoutEntries[i].position.left + "%;";
div = div + "height:" + layoutEntries[i].size.height + "%;";
div = div + "width:" + layoutEntries[i].size.width + "%;";
div = div + "\"></nv-single-layout-entry>";
var el = $compile(div)(scope);
element.append(el);
elementCol[layoutEntries[i].id] = 1;
}
};
}
function controller($scope, $element) {
}
}
})();
答案 0 :(得分:15)
将scope.$watch与自定义监视功能结合使用:
scope.$watch(
function () {
return [element[0].offsetWidth, element[0].offsetHeight].join('x');
},
function (value) {
console.log('directive got resized:', value.split('x'));
}
)
答案 1 :(得分:13)
您通常希望观看元素的select 'min' as k, min(salary) as v from parent
union
select 'avg' as k, avg(salary) as v from parent
union
select 'max' as k, max(salary) as v from parent
和offsetWidth
属性。使用更新版本的AngularJS,您可以在链接功能中使用offsetHeight
:
$scope.$watchGroup
但是,您可能会发现以这种方式直接观看元素属性时更新速度很慢。
为了使您的指令更具响应性,您可以使用app.directive('myDirective', [function() {
function link($scope, element) {
var container = element[0];
$scope.$watchGroup([
function() { return container.offsetWidth; },
function() { return container.offsetHeight; }
], function(values) {
// Handle resize event ...
});
}
// Return directive definition ...
}]);
来降低刷新率。以下是以可配置的毫秒速率观察元素大小的可重用服务示例:
$interval
使用这种服务的指令看起来像这样:
app.factory('sizeWatcher', ['$interval', function($interval) {
return function (element, rate) {
var self = this;
(self.update = function() { self.dimensions = [element.offsetWidth, element.offsetHeight]; })();
self.monitor = $interval(self.update, rate);
self.group = [function() { return self.dimensions[0]; }, function() { return self.dimensions[1]; }];
self.cancel = function() { $interval.cancel(self.monitor); };
};
}]);
请注意app.directive('myDirective', ['sizeWatcher', function(sizeWatcher) {
function link($scope, element) {
var container = element[0],
watcher = new sizeWatcher(container, 200);
$scope.$watchGroup(watcher.group, function(values) {
// Handle resize event ...
});
$scope.$on('$destroy', watcher.cancel);
}
// Return directive definition ...
}]);
事件处理程序中对watcher.cancel()
的调用;这可以确保$scope.$destroy
实例在不再需要时被销毁。
可以找到一个JSFiddle示例here。
答案 2 :(得分:7)
以下是您需要执行的示例代码:
APP.directive('nvLayout', function ($window) {
return {
template: "<div></div>",
restrict: 'EA',
link: function postLink(scope, element, attrs) {
scope.onResizeFunction = function() {
scope.windowHeight = $window.innerHeight;
scope.windowWidth = $window.innerWidth;
console.log(scope.windowHeight+"-"+scope.windowWidth)
};
// Call to the function when the page is first loaded
scope.onResizeFunction();
angular.element($window).bind('resize', function() {
scope.onResizeFunction();
scope.$apply();
});
}
};
});
答案 3 :(得分:2)
使用$ watch检测元素大小/位置变化的唯一方法是使用$ interval或$ timeout等常量更新范围。虽然可能,但它可能会成为一项昂贵的操作,并且会严重降低您的应用程序速度。
您可以通过调用来检测元素更改的一种方法
requestAnimationFrame
。
var previousPosition = element[0].getBoundingClientRect();
onFrame();
function onFrame() {
var currentPosition = element[0].getBoundingClientRect();
if (!angular.equals(previousPosition, currentPosition)) {
resiszeNotifier();
}
previousPosition = currentPosition;
requestAnimationFrame(onFrame);
}
function resiszeNotifier() {
// Notify...
}
这是一个Plunk展示了这一点。只要你移动盒子,它就会保持红色。
答案 4 :(得分:0)
Eliel的回答略有不同,对我有用。在directive.js中:
$scope.onResizeFunction = function() {
};
// Call to the function when the page is first loaded
$scope.onResizeFunction();
angular.element($(window)).bind('resize', function() {
$scope.onResizeFunction();
$scope.$apply();
});
我打电话
$(window).resize();
来自我的app.js.该指令的d3图表现在调整大小以填充容器。
答案 5 :(得分:0)
以下是我对此指令的看法(使用Webpack
作为捆绑器):
module.exports = (ngModule) ->
ngModule.directive 'onResize', ['Callback', (Callback) ->
restrict: 'A'
scope:
onResize: '@'
onResizeDebounce: '@'
link: (scope, element) ->
container = element[0]
eventName = scope.onResize || 'onResize'
delay = scope.onResizeDebounce || 1000
scope.$watchGroup [
-> container.offsetWidth ,
-> container.offsetHeight
], _.debounce (values) ->
Callback.event(eventName, values)
, delay
]