在 Angular 中,如何从指令访问我编译的模板

In Angular how can I access my compiled template from a directive?

本文关键字:访问 编译 指令 Angular      更新时间:2023-09-26

我有这样的指令

return {
  scope:{
    divid: '@'
  },
  template: '<div id="{{divid}}"></div>'
}

和这样的实例

<direct divid="some-id"></direct>

我想在我知道模板已被编译并且 id 设置为"some-id"后运行一些 javascript。我尝试了一个控制器、前链接和后链接函数,但如果我在这些函数中设置断点,我可以看到 id 在所有情况下仍然等于"{{divid}}"。有没有办法这样做?我知道我可以通过编译和链接函数访问模板元素,但如果可以的话,我想避免这种情况,因为它使我的代码更加简洁和可读。

您可以将该段代码包装在链接函数中$timeout内,它将确保您的元素完全呈现,因为$timeout仅在当前摘要周期完成后运行(前提是您已经在当前摘要周期之前设置了 id)。请记住,如果在超时内未执行任何范围更新,请使用第三个参数(设置为 false)来启动摘要循环运行。

如果您不确定何时设置 id,尤其是异步设置 id 时(即异步填充 divid="{{someId}}"someId 时),您也可以使用一次性手表。

然后还有一个非标准的私有属性,其范围也称为$$postDigest,因为它是内部属性实现可以在任何未来的版本中更改,因此使用它需要您自担风险。

angular.module('app', []).directive('direct', function($timeout) {
  return {
    scope: {
      divid: '@'
    },
    restrict: 'EA',
    template: '<div id="{{divid}}"></div>',
    link: function(scope, element) {
      console.log('Before digest-->', element.find('div').attr('id'));
      //using timeout
      $timeout(function() {
        console.log('In timeout-->', element.find('div').attr('id'));
      }, false);
      //Using non standard postdigest
      scope.$$postDigest(function() {
        console.log('In postdigest-->', element.find('div').attr('id'));
      });
      //Setting up a onetime watch
      var unWatch = scope.$watch(function() {
        return element.find('div').attr('id');
      }, function(val) {
        if (val) {
          unWatch();
          console.log('One time watch-->', element.find('div').attr('id'), val);
        }
      })
    }
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<div ng-app="app">
  <direct divid="someid"></direct>
  Nothing much here, See the console
</div>