在AngularJS中发生ng-if,ng-show等之后,我该如何做一些动作?

时间:2018-05-25 04:10:19

标签: angularjs angularjs-directive

我正在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-ifng-show的动态偏见,它不会起作用,因为渲染后计算的位置会发生变化。

<div ng-if="variable" style="width: 200px; height: 200px"></div>
<div id="dummy" style="width: 400px; height: 400px;"></div>
<reposition></reposition>

如果我可以拦截ng-ifng-show来执行以下操作:ng-ifcode to reposition那么我可以让它发挥作用。我正在考虑编写一个新的指令ng-hack-if,也可以这样做。

这是codepen。只需将指令的ng-showtrue切换为false即可。当true一切正常时,reposition工作正常。但是当它为false时,reposition认为存在div,但Angular会在评估周期中将其删除。当AngularJS进行DOM修改时,我只需要调用moveContainerAccordingToHolder,在这种情况下调用ng-show

5 个答案:

答案 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

Here is a DEMO for the same

答案 3 :(得分:0)

以指令方式进行。从你将要创建的指令中,将逻辑放在那里。

答案 4 :(得分:0)

指令的$scope.$apply函数中over-riding指令的父级$scope.$digestlink的选项也很好。这样,对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;
};