angularjs:如何在不使用jquery的情况下从指令中的$element获取宽度

angularjs:如何在不使用jquery的情况下从指令中的$element获取宽度,angularjs,Angularjs,我尝试从指令中的$element获取宽度。但是,它继续返回0 你能告诉我有什么问题吗?你能告诉我解决办法吗 为了解决这个问题,我创建了一个演示: 指示 angular.module('testApp').directive('testDirective', testDirective) function testDirective() { return { restrict: 'E', controller: 'TestController',

我尝试从指令中的$element获取宽度。但是,它继续返回0

你能告诉我有什么问题吗?你能告诉我解决办法吗

为了解决这个问题,我创建了一个演示:

  • 指示

    angular.module('testApp').directive('testDirective', testDirective)
    function testDirective() {
        return {
            restrict: 'E',
            controller: 'TestController',
            controllerAs: 'vm',
            bindToController: true,
            scope: {}
        }
    }
    
  • 控制器

    angular.module('testApp').controller('TestController', TestController);
    
    TestController.$inject = ['$element'];
    
    function TestController($element) {
        var vm = this;
    
        init()
    
        function init(){
        vm.elWidth0 = $element.find("div")[0].clientWidth; 
        vm.elWidth1 = $element.find("div")[0].offsetWidth; 
        vm.elWidth2 = $element.prop('clientWidth'); 
        console.log(vm.elWidth0); //return 0
        console.log(vm.elWidth1); //return 0
        console.log(vm.elWidth2); //return 0
        }
    }
    
  • html

    <test-directive>
        <div>
            <button>a</button>
            <button>c</button>
            <button>d</button>
            <button>e</button>
            <button>f</button>
        </div>
    </test-directive>
    
    
    A.
    C
    D
    E
    F
    

感谢您的建议

看看这个plnkr:

您似乎没有获得对元素的正确引用。尝试改用
querySelector

$element[0].querySelector('button').clientWidth;
更新

在指令中放置DOM操作的最佳位置是
link
函数(实际上是
post-link
),因为链接发生在指令html编译之后

控制器也是在编译指令html之后创建的,但是最好使用控制器来分离需要与angular服务通信的逻辑。关于指令链接和控制器,有一些非常好的信息

然后,您的指令可以如下所示:

function testDirective() {
  return {
    restrict: 'E',
    controller: 'TestController',
    controllerAs: 'vm',
    bindToController: true,
    scope: {}, 
    link: function(scope, element, attrs) {
      scope.elWidth0 = element.find("div")[0].clientWidth; 
      scope.elWidth1 = element.find("div")[0].offsetWidth; 

      console.log(scope.elWidth0);
      console.log(scope.elWidth1);
    }
  }
}

看看这个plnkr:

您似乎没有获得对元素的正确引用。尝试改用
querySelector

$element[0].querySelector('button').clientWidth;
更新

在指令中放置DOM操作的最佳位置是
link
函数(实际上是
post-link
),因为链接发生在指令html编译之后

控制器也是在编译指令html之后创建的,但是最好使用控制器来分离需要与angular服务通信的逻辑。关于指令链接和控制器,有一些非常好的信息

然后,您的指令可以如下所示:

function testDirective() {
  return {
    restrict: 'E',
    controller: 'TestController',
    controllerAs: 'vm',
    bindToController: true,
    scope: {}, 
    link: function(scope, element, attrs) {
      scope.elWidth0 = element.find("div")[0].clientWidth; 
      scope.elWidth1 = element.find("div")[0].offsetWidth; 

      console.log(scope.elWidth0);
      console.log(scope.elWidth1);
    }
  }
}

最可能的解释是该元素尚未实际渲染。您可能应该使用
链接
/
链接.post
功能来运行您的身高检测代码,即使如此,您也可能需要在
$timeout
hi@Phil中运行它。如果控制器中有必要,我应该怎么做。还有,“$timeout”方法是最佳实践吗?最可能的解释是元素还没有实际渲染。您可能应该使用
链接
/
链接.post
功能来运行您的身高检测代码,即使如此,您也可能需要在
$timeout
hi@Phil中运行它。如果控制器中有必要,我应该怎么做。还有,“$timeout”方式是最佳实践吗?嗨@paultrone。我很抱歉。我制作了一个错误的演示。所以,我纠正了一个demohi@paultrone。我很抱歉。我制作了一个错误的演示。所以,我更正了一个演示