在 ng-if、ng-show 等发生在 AngularJS 之后,我该如何做一些动作?
How do I do some action after ng-if, ng-show etc happens in AngularJS?
我正在使用 position: absolute
处理 workaround,需要计算 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
。
您可以尝试使用 AngularJS
的 ngStyle
指令。它可以帮助您动态更改任何元素的 CSS。检查这个 link.
以指令的方式进行。从您将创建的指令中,将逻辑放在那里。
请检查这个答案,
我制作了一个切换函数并制作了一个 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
您可以延迟函数的执行,直到 DOM 使用 setTimeOut 函数完成渲染。
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"。
指令的 link
函数中的 over-riding 指令的父项 $scope.$apply
和 $scope.$digest
的选项也很好。这样,对局部的任何更改都会触发重新定位,这正是我想要的。
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;
};
我正在使用 position: absolute
处理 workaround,需要计算 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
。
您可以尝试使用 AngularJS
的 ngStyle
指令。它可以帮助您动态更改任何元素的 CSS。检查这个 link.
以指令的方式进行。从您将创建的指令中,将逻辑放在那里。
请检查这个答案,
我制作了一个切换函数并制作了一个 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
您可以延迟函数的执行,直到 DOM 使用 setTimeOut 函数完成渲染。
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"。
指令的 link
函数中的 over-riding 指令的父项 $scope.$apply
和 $scope.$digest
的选项也很好。这样,对局部的任何更改都会触发重新定位,这正是我想要的。
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;
};