- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
更新:我悬赏这个问题。我不是在寻找黑客或解决方法。我正在寻找一种官方方式来访问 Angular 组件中的 dom,并解释为什么我看到的行为($postLink 运行到早期)似乎与官方文档相矛盾。
官方文档状态 ( here ):
$postLink() - Called after this controller's element and its children have been linked. Similar to the post-link function this hook can be used to set up DOM event handlers and do direct DOM manipulation
原始问题:我这里有一个问题的例子 -> http://plnkr.co/edit/rMm9FOwImFRziNG4o0sg?p=preview
我正在使用一个 Angular 组件,我想修改 post 链接函数中的 dom,但它不起作用,似乎该函数运行得太早,在模板实际在 dom 中准备好之前 Angular 处理。
在 html 页面中,我有这个:
<my-grid grid-id="'foo'"></my-grid>
组件定义为:
appModule.component('myGrid',{
controller: gridController,
bindings: {
"gridId": "<",
},
templateUrl: 'gridTemplate'
});
在组件模板中我有这个:
<table id='{{$ctrl.gridId}}'>
...
(毫无疑问,绑定(bind)本身有效。最终,在 html 中,表格的 id 正如预期的那样是“foo”)。
在 Controller 中,我有这样的东西:
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函数执行时,表在dom中但它的id属性仍然是{{$ctrl.gridId}}
而不是 foo
,所以 document.getElementById()
什么也找不到。这似乎与文档形成对比。
我错过了什么?是否有不同的方式来访问组件中的 dom?
更新2:今天我发现指令的常规链接功能也出现了同样的问题,它不仅限于组件。因此,显然我误解了“直接进行 DOM 操作”的含义 - 链接函数在与 dom 分离的元素上运行,因此将 document
对象与选择器一起使用是无用的。
最佳答案
有关$postLink()
的文档是正确的。它在其 Controller 的元素及其子元素已链接后调用。这并不意味着您会立即看到指令的结果。也许它正在调用 $http
并在结果到达后插入结果。也许它正在注册一个观察者,该观察者反过来设置结果,就像大多数 Angular 的内置指令一样。
你的情况的根本问题是你想在编译插值之后执行 DOM 操作,或者更好的是,在他们注册的观察者有时间运行一次之后。
不幸的是,没有官方方式来做到这一点。尽管如此,还是有一些方法可以实现这一点,但您不会在文档中找到它们。
在编译插值后运行函数的两种流行方式是:
立即使用 $timeout
(因为它默认为 0):$timeout(function() {/* Your code goes here */});
使用由 Angular's jqLite 提供的 .ready()
在您的情况下,一旦具有给定 ID 的元素存在,您最好使用观察者运行函数:
var deregistrationFn = $scope.$watch(() => {
return document.getElementById(this.gridId);
}, (newValue) => {
if (newValue !== null) {
deregistrationFn();
// Your code goes here
}
});
最后,在我看来,我相信每当您需要等待插值被编译,或者某些指令插入它们的值时,您就没有遵循Angular 的构建方式。在您的情况下,为什么不创建一个新组件 myGridTable
需要 myGrid
作为父级,并在其中添加其适当的逻辑。这样,每个组件的职责都得到了更好的定义,并且更容易测试。
关于javascript - Angular 组件/指令的 $postLink 运行得太早,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37146700/
每当用户旋转手机时,我都需要读取 DIV 的像素宽度。在 iOS 上,以下代码将在方向完成后打印出 DIV 的宽度。但是,在 Android 上,代码将在方向开始之前打印出 DIV 的宽度。 HTML
我的网站正在使用jquery.load()在页面的一大块上进行导航。我真的很欣赏只包含加载内容的特定部分的能力,这里是 id="content"的 div: $(frame_selector).loa
我是一名优秀的程序员,十分优秀!