AngularJS-绑定到指令调整大小
调整指令大小时如何通知我? 我试过了AngularJS-绑定到指令调整大小,angularjs,angularjs-directive,Angularjs,Angularjs Directive,调整指令大小时如何通知我? 我试过了 element[0].onresize = function() { console.log(element[0].offsetWidth + " " + element[0].offsetHeight); } 但它并没有调用函数 (function() { 'use strict'; // Define the directive on the module. // Inject the dependencies
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) {
}
}
})();
(函数(){
"严格使用",;
//在模块上定义指令。
//注入依赖项。
//指向指令定义函数。
angular.module('app').directive('nvLayout',['$window','$compile','layoutDirective]);
函数layoutDirective($window,$compile){
//用法:
//
//创建:
//
var指令={
链接:链接,
限制:“EA”,
范围:{
布局:“=”,
已选择:“&onSelected”
},
模板:“”,
控制器:控制器
};
返回指令;
功能链接(范围、元素、属性){
var elementCol=[];
var onSelectedHandler=scope.selected();
元素上(“调整大小”,函数(){
log(“调整大小”);
});
$(窗口).on(“调整大小”,scope.sizeNotifier);
作用域:“$destroy”,函数(){
$(window).off(“resize”、$scope.sizeNotifier);
});
scope.sizeNotifier=函数(){
警报(“正在调整窗口大小…”);
};
scope.onselected=函数(id){
onSelectedHandler(id);
};
范围:$watch(函数(){
返回scope.layounterties.length;
},
函数(值){
//布局已更改
activateLayout(范围、布局);
});
函数activateLayout(layoutEntries){
for(var i=0;i
以下是您需要执行的操作的示例代码:
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();
});
}
};
});
APP.directive('nvLayout',函数($window){
返回{
模板:“”,
限制:“EA”,
链接:函数postLink(范围、元素、属性){
scope.onResizeFunction=函数(){
scope.windowHeight=$window.innerHeight;
scope.windowWidth=$window.innerWidth;
console.log(scope.windowHeight+“-”+scope.windowWidth)
};
//首次加载页面时调用函数
scope.onResizeFunction();
angular.element($window.bind('resize',function()){
scope.onResizeFunction();
作用域:$apply();
});
}
};
});
与自定义手表功能一起使用:
scope.$watch(
function () {
return [element[0].offsetWidth, element[0].offsetHeight].join('x');
},
function (value) {
console.log('directive got resized:', value.split('x'));
}
)
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 ...
}]);
使用$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...
}
这是一个演示这一点的砰砰声。只要你移动盒子,它就会保持红色
您通常希望查看元素的
偏移网络宽度
和偏移网络宽度
属性。对于AngularJS的最新版本,您可以在链接函数中使用$scope.$watchGroup
:
scope.$watch(
function () {
return [element[0].offsetWidth, element[0].offsetHeight].join('x');
},
function (value) {
console.log('directive got resized:', value.split('x'));
}
)
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 ...
}]);
注意在$scope.$destroy
事件处理程序中调用watcher.cancel()
;这确保不再需要时销毁$interval
实例
可以找到一个JSFIDLE示例。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图表现在可以调整大小以填充容器。以下是我对该指令的看法(使用
Webpack
作为捆绑包):
我试着理解代码的目的,但这对我来说很难。我已经消除了代码对JQuery的依赖,您可以在这里检查:我只是想在调整指令元素的大小时得到通知。我可以听整个页面,但我想知道elemnt何时导致指令move@li-raz:完全实现:-)如果只调整指令get的大小,而不调整窗口本身,这将不起作用。。。虽然我不认为你需要调用Apply,但我已经尝试过了,但它通常会向我显示旧的值。我有一个边栏,可以使用按钮隐藏或显示,当我单击时,摘要循环发生,watch函数告诉我元素的大小没有改变,然后元素被调整大小,这会在下一个循环中出现,从而导致故障。有什么想法吗?@HernanRajchert(以及任何其他未来的读者),这是因为可以计算为CSS高度+CSS填充-水平滚动条的高度(如果存在)。你想要的是。观看
元素[0]。远视(和宽度)应该可以。@JordanCarroll对我来说,使用远视而不是clientHeight并没有解决问题。你说得对,我相应地调整了答案。感谢您指出这一点。我对digest cycle也有同样的问题,resize事件只在下一次调用时触发。我的问题在这里。不幸的是,看着OutthItHeal/Stand似乎没有解决这个问题。任何想使用这个方法的人都应该考虑替换<代码> $间隔(Self.Up更新,Read);<代码>具有$interval(self.update,rate,0,false)代码>,它明确表示最后不要调用$apply。否则,范围的摘要将为ca