如何通过动态选择器查询Angularjs指令嵌套DOM元素?

时间:2016-06-14 17:09:48

标签: angularjs angularjs-directive angular-directive angular-template angular-directive-link

父模板中的指令分配:

<div badge></div>

指令模板templates/badge.html
使用指令$id注意动态ID的分配。

<div>
    <span id="id{{ ::$id }}_name">Nik Sumeiko, Frontend engineer</span>
</div>

指令:

angular.module('app').directive('badge', () => ({
  restrict: "A",
  replace: true,
  templateUrl: "templates/badge.html",
  link: (scope, element, attributes) => {

    // Tries to query nested DOM element by a dynamic selector.
    const name = element.find(`#id${scope.$id}_name`);

    console.log(name.length, element.html());
  }
}));

根据控制台输出,可以清楚地看到指令模板还没有编译其动态值:

0 "
    <div>
      <span id="id{{ ::$id }}_name">Nik Sumeiko, Frontend engineer</span>
    </div>
"

如何通过动态选择器查询嵌套元素?是否有任何其他指令方法在Angular呈现模板的动态值之后调度?

请不要建议使用$timeout注入函数来延迟link方法中的模板渲染,因为我不认为这是正确的方法......

1 个答案:

答案 0 :(得分:2)

这里引用了角documentation

  

链接之后,直到调用$ digest后才会更新视图,这通常由Angular自动完成。

这就是为什么你无法在他们的id中找到包含表达式的元素 - 当时视图没有更新。

这里有解决方法:

创建元素并手动将其附加到DOM

这样你就可以引用元素了,所以你不必查询它:

link: (scope, element, attributes) => {
    let span = $compile('<span id="id{{ ::$id }}_name">Nik Sumeiko, Frontend engineer</span>')(scope);
    // do something to span ...
    element.append(span);
}

使用$ timeout

你可以使用$timeout零延迟,这不是错误的方法。 $timeout将在当前$digest周期后立即执行您的代码,这意味着在更新视图绑定之后:

link: (scope, element, attributes) => {
    $timeout(function() {
        let span = element[0].querySelector(`#id${scope.$id}_name`);
    });
}