我正在workaround使用position: absolute
,需要计算div
的位置。
<html>
<!-- this iframe will positioned by an angular partial through a directive -->
<iframe style="position: absolute; width: 400px; height: 400px";></iframe>
<div id="angular"></div>
<html>
它适用于静态部分,如下所示:
<div id="dummy" style="width: 400px; height: 400px;"></div>
<reposition></reposition>
但对于ng-if
或ng-show
的动态偏见,它不会起作用,因为渲染后计算的位置会发生变化。
<div ng-if="variable" style="width: 200px; height: 200px"></div>
<div id="dummy" style="width: 400px; height: 400px;"></div>
<reposition></reposition>
如果我可以拦截ng-if
和ng-show
来执行以下操作:ng-if
,code to reposition
那么我可以让它发挥作用。我正在考虑编写一个新的指令ng-hack-if
,也可以这样做。
这是codepen。只需将指令的ng-show
从true
切换为false
即可。当true
一切正常时,reposition
工作正常。但是当它为false
时,reposition
认为存在div
,但Angular会在评估周期中将其删除。当AngularJS进行DOM修改时,我只需要调用moveContainerAccordingToHolder
,在这种情况下调用ng-show
。
答案 0 :(得分:2)
您可以使用 setTimeOut 函数延迟执行函数,直到DOM完成渲染。
module1.directive('reposition', [function() {
return {
restrict: 'E',
replace: true,
link: function(scope, element, attrs) {
var holder = angular.element(
document.getElementById("holder")
)[0];
setTimeout(function() {
window.moveContainerAccordingToHolder(holder);
},0);
},
template: directiveTemplate
};
}]);
这也适用于ng-show =“false”。
答案 1 :(得分:1)
您可以尝试使用ngStyle
的{{1}}指令。它可以帮助您动态更改任何元素的CSS。请检查此link。
答案 2 :(得分:1)
请检查此答案,
我制作了一个切换功能,并使variable
show
显示并隐藏了div
,并在该功能中调用了moveContainerAccordingToHolder
。
我添加了click to toggle
按钮,请点击button
以下是您的指示:
directiveTemplate = `
<div id="directive">
<span ng-click="toggleShow()"> Click to Toggle </span>
<div id="pre" style="width: 102.4px; height: 35.9px" ng-show="show">
Pre
</div>
<div id="holder" style="width: 102.4px; height: 76.8px; border:1pt dashed gray;">
</div>
<div id="post" width="102.4">
Post
</div>
</div>`;
// Integration Begins
function moveContainerAccordingToHolder(holder) {
var reposition = document.getElementById('reposition');
reposition.style.border = "1pt solid green";
reposition.style.position = "absolute";
var holderTop = holder.getBoundingClientRect().top;
var holderLeft = holder.getBoundingClientRect().left;
var scrollTop = document.documentElement.scrollTop;
var scrollLeft = document.documentElement.scrollLeft;
holderTop = holderTop + scrollTop + 1;
holderLeft = holderLeft + scrollLeft + 1;
holderTop = String(holderTop) + "px";
holderLeft = String(holderLeft) + "px";
reposition.style.top = holderTop;
reposition.style.left = holderLeft;
reposition.style.display = "block";
}
// Integration Ends
// Angular Begins
(function(angular) {
'use strict';
var module1 = angular.module('module', []);
module1.controller('Controller', ['$scope', function($scope) {
}]);
module1.directive('reposition', [function() {
return {
restrict: 'E',
replace: true,
link: function(scope, element, attrs) {
scope.show = true;
var holder = angular.element(
document.getElementById("holder")
)[0];
window.moveContainerAccordingToHolder(holder);
scope.toggleShow = function(){
scope.show = !scope.show
window.moveContainerAccordingToHolder(holder);
}
},
template: directiveTemplate
};
}]);
})(window.angular);
// Angular Ends
答案 3 :(得分:0)
以指令方式进行。从你将要创建的指令中,将逻辑放在那里。
答案 4 :(得分:0)
指令的$scope.$apply
函数中over-riding指令的父级$scope.$digest
和link
的选项也很好。这样,对partial的任何更改都会触发重新定位,这就是我想要的。
var parentApply = scope.$parent.$apply;
var parentDigest = scope.$parent.$digest;
scope.$parent.$apply = function() {
console.log("Apply was called");
var r = parentApply.call(scope.$parent);
moveContainerAccordingToHolder(holder);
return r;
};
scope.$parent.$digest = function() {
console.log("Digest was called");
var r = parentDigest.call(scope.$parent);
moveContainerAccordingToHolder(holder);
return r;
};