Как мне сделать какое-нибудь действие после ng-if, ng-show и т. Д. В AngularJS? - PullRequest
0 голосов
/ 25 мая 2018

Я работаю над обходным решением , используя 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, которая будет делать то же самое.

Вот кодекс .Просто переключите директиву ng-show с true на false.Когда это true все работает, reposition работает нормально.Но когда это false, reposition считает, что есть div, но Angular удаляет его в цикле оценки.Мне просто нужно вызвать moveContainerAccordingToHolder, когда AngularJS выполняет модификацию DOM, то есть в этом случае ng-show.

Ответы [ 5 ]

0 голосов
/ 26 мая 2018

Опция переопределение родительской директивы $scope.$apply и $scope.$digest изнутри функции директивы link также подойдет.Таким образом, любое изменение в партиале вызовет изменение положения, что я и хотел.

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;
};
0 голосов
/ 25 мая 2018

Вы можете отложить выполнение функции до тех пор, пока 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".

0 голосов
/ 25 мая 2018

Делайте это директивным путем.И из директивы, которую вы создадите, поместите логику туда.

0 голосов
/ 25 мая 2018

Пожалуйста, проверьте этот ответ,

Я сделал функцию переключения и сделал 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

ВотДЕМО для того же

0 голосов
/ 25 мая 2018

Вы можете попробовать с директивой ngStyle AngularJS.Это помогает вам динамически изменять CSS любого элемента.Проверьте эту ссылку .

...