28

我正在尝试创建一个以 div 为中心的指令。

到目前为止,我有这个代码:

app.directive("setcenter", function () {
    return {
        scope:{
            setcenter: '='
        },
        link: function (scope, element, attrs) {

            scope.$watch('setcenter', function (newValue) {
                if (newValue == true) {
                    var width = element.width();
                    element.css('position', 'absolute');
                    element.css('top', '80px');
                    element.css('left', '50%');
                    element.css('z-index', '200');
                    element.css('margin-left', '-' + width / 2 + 'px');
                }
            });
        }
    }
});

问题是元素的宽度。该指令的重点是使用该指令的 div 没有设置宽度。我希望这个指令能够计算出宽度并将 div 居中。

我遇到的问题是当指令被调用时,div的实际宽度还不知道。当我在我的情况下使用它时,div 是 800px,但是当页面完成加载时,div 是 221px。

那么,我该怎么做才能等到知道 div 的实际宽度?

4

4 回答 4

31

首先,当我为指令而不是链接函数定义控制器时,我只使用了这个逻辑。所以在链接函数中定义它可能会导致不同的行为,但我建议你先在那里尝试,如果你不能让它工作,然后切换到使用控制器。

据我所知,您需要进行的唯一更改是将 $scope 更改为范围调用并将 $element 更改为元素,因为依赖注入对象成为标准链接函数参数。

  $scope.getElementDimensions = function () {
    return { 'h': $element.height(), 'w': $element.width() };
  };

  $scope.$watch($scope.getElementDimensions, function (newValue, oldValue) {
    //<<perform your logic here using newValue.w and set your variables on the scope>>
  }, true);

  $element.bind('resize', function () {
    $scope.$apply();
  });

在阅读了关于观看 $window 而不是当前元素的非常相似类型的用法之后,我想到了这种用法的想法,可以在此处找到原始作品。

Angular.js:在页面加载时设置元素高度

于 2013-09-30T02:52:43.720 回答
7

詹姆斯的回答让我:

app.directive('measureInto', function () {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                scope.$watch(function() {
                    return element[0].clientWidth;
                }, function(value){
                    scope[attrs.measureInto] = element[0].clientWidth + 10;
                });
            }
        };
    });

因此,在运行时,我添加它并分配给我想要的任何范围变量,我正在寻找的元素的宽度

于 2015-10-28T18:29:31.370 回答
1

我遇到了类似的问题,发现当页面上的所有 ng-ifs(或使用 ngAnimate 的任何其他内容)都已解决时,尺寸确实正确 - 这里可能发生类似的事情。如果是这样,这将在不添加任何新侦听器的情况下解决问题:

$scope.tryGetElementDimensions = function () {
    if (!angular.element("your-element") || ((angular.element("your-element")[0].classList).contains("ng-animate")
       $timeout(function() {
           $scope.tryGetElementDimensions()
       })
    }
    else {
        $scope.getElementDimensions()
    } 

$scope.getElementDimensions = function (){
    //whatever you actually wanted to do
}

link: function (scope, element, attrs) {
    $scope.tryGetElementDimensions()
}

Angular 在制作动画时添加了 ng-animate 和 ng-enter、ng-leave 类,当这些类全部被删除时,你可以确信它已经完成。$timeout 没有第二个参数只是等待下一个摘要。

于 2016-04-01T00:14:46.257 回答
1

还不能评论,所以这个答案。找到了一个类似的解决方案,就像 strom2357 建议的那样。$timeout 可以很好地让你知道 dom 何时准备就绪,而且非常简单。我正在使用这个解决方案来获取 ui-view 元素的宽度。在小提琴中找到它。

var app = angular.module('app', []);

app.controller('MyController', function($timeout, $scope){

  $timeout(function(){
    //This is where you would get width or height of an element
    alert('DOM ready');
  });

  alert('DOM not ready');

});
于 2016-05-10T13:35:01.497 回答