$postLink 成分/指示 angular, 推出太早了

更新:

我指定了这个问题的奖励。 我不是在寻找卡其色或旁路路径。 我正在寻找一种官方访问方式 dom 在组件中 angular, 并解释为什么我看到的行为 /$postLink 在开始前工作/, 它似乎与官方文件相反。

官方文件宣布 /
https://docs.angularjs.org/guide/component
/:

$postLink//- 此控制器及其子公司的元素相关联。 喜欢功能 post-link, 此钩子可用于配置事件处理程序。 DOM 并执行直接操纵 DOM

原始问题:

这里有一个例子问题 - >
http://plnkr.co/edit/rMm9FOwIm ... eview
我使用一个组件 angular 我想改变 dom 在功能中 post link, 但它不起作用,似乎函数在模板真的准备好之前发起了太早 dom 毕竟处理后 angular.

到页面 html 我有这个:


<my-grid grid-id="'foo'"></my-grid>


该组件定义为:


appModule.component/'myGrid',{
controller: gridController,
bindings: {
"gridId": "<",
},
templateUrl: 'gridTemplate'
}/;


在组件模板中我有它:


<table id="{{$ctrl.gridId}}">
...


/绑定本身有效,毫无疑问。 最终,在 html 表ID相等 'foo', 正如预期的那样/.

在控制器中,我有这样的东西:


function gridController/$scope, $compile, $attrs/ {
console.log /"grid id is: " + this.gridId/; // 'foo'

this.$postLink = function// {
var elem = document.getElementById/this.gridId/;
// do something with elem, but elem is null
}
}


调试时,我看到执行函数时 $postLink 表是b。 dom, 但她的属性 id 仍然
{{$ctrl.gridId}}

反而
foo

, 所以
document.getElementById//

没有什么能找到任何东西。 这似乎与文件相矛盾。

我错过了什么? 是否有另一种方法可以访问 dom 在组件中?

更新 2:

今天我意识到,由于参考指令的通常函数出现了相同的问题,因此不限于组件。 因此,显然,我误解了价值 "do direct DOM manipulation" - 功能 link 适用于分开的元素 dom, 因此,使用设施
document

选择器是无用的。
</table>
已邀请:

詹大官人

赞同来自:

文档
$postLink//

这是正确的。 在其控制器的元素及其子元素相关联后调用它。 这并不意味着您将立即看到指令的结果。 也许他会导致
$http

并在他来就立即插入结果。 也许这是一个观察者的注册,反过来,这反过来建立了结果,

大多数内置指令如何

Angular .

您案例中的主要问题是 , 你想表演什么 DOM 操作后

编译插值

, 甚至更好,在他们的注册观察者管理一次运行后。

很遗憾,

官方方法

不这样做。 尽管如此,有些方法可以做到这一点,但你不会发现他们在文档中列出。

两个流行的方式

编译插值后启动功能

:

使用
$timeout

不延误/ 默认 0/:
$timeout/function// { /* Your code goes here */ }/;


使用
.ready//

, 提供了这一点
https://docs.angularjs.org/api ... ement

在您的情况下,您可以更好地使用Observer从给定的元素后立即启动函数 ID 存在:


var deregistrationFn = $scope.$watch/// => {
return document.getElementById/this.gridId/;
}, /newValue/ => {
if /newValue !== null/ {
deregistrationFn//;

// Your code goes here
}
}/;


最后,在我看来,我相信,只要你需要等待插值或某些指令要插入意义,你就不会遵循

建筑物的方法

Angular . 在您的情况下,为什么不创建新组件
myGridTable

, 这需要
myGrid

作为父母,并在那里添加相应的逻辑。 因此,每个组件的责任要更好地确定,并且更容易检查。

小明明

赞同来自:

误解在于如何循环 angular $digest 与控制器生命周期的事件结合使用 /生命周期指令的事件/.

控制器生命周期的每个事件 / 指令被称为内部 $apply., 所以 DOM 仅更新以反映更改后
https://docs.angularjs.org/gui ... -loop
$digest .

功能 post link 它在连接一切都会之后开始,但它是
http://odetocode.com/blogs/sco ... .aspx
DOM 更新以反映任何绑定,因为它是循环内部启动的最后一个函数 $digest. 它的意思是 , 什么试图要求 DOM 对于受约束力影响的任何东西,它都不工作 /例如,
ng-repeat

或者,在您的情况下,相关价值/. 但是,正如他们在文件中所说的那样,绑定 DOM 它已经在运行,因此创建源模板,可以更改。

您需要请求 DOM 应用绑定后,您需要在完成当前循环后运行代码。 $digest. 这意味着使用
$timeout

延迟 0, 这将是
http://blog.brunoscopelliti.co ... ring/
$digest .


function gridController/$scope, $compile, $attrs, $timeout/ {
console.log /"grid id is: " + this.gridId/; // 'foo'

this.$postLink = function// {
$timeout/function// {
var elem = document.getElementById/this.gridId/;
// do something with elem now that the DOM has had it's bindings applied
}/;
}
}

要回复问题请先登录注册