我在我的组件的template.html中设置了一些语义UI标签,如下所示:
<div class="ui top attached tabular menu">
<a class="item active" data-tab="global" >Global</a>
<a class="item" data-tab="gen_config" >Config</a>
<a class="item" data-tab="service" >Service</a>
<a class="item" data-tab="change" >Change</a>
</div>
<div class="ui bottom attached tab segment active" data-tab="global"> //some stuff// </div>
<div class="ui bottom attached tab segment active" data-tab="gen_config"> //some stuff// </div>
<div class="ui bottom attached tab segment active" data-tab="service"> //some stuff// </div>
<div class="ui bottom attached tab segment active" data-tab="change"> //some stuff// </div>
我在自定义JS文件中实例化了标签,该文件通过index.html页面加载并包含:
$(document).ready(function () {
$('.ui.dropdown').dropdown();
$('.top.menu .item').tab();
$('.tabular.menu .item').tab();
});
每当我路由到包含这些选项卡的组件时,选项卡都不起作用。但是,每当我在该组件上刷新页面时,标签就会开始工作。有没有理由发生这种情况?
我最关心的是为什么选项卡在路由到组件后不起作用,但仅在路由后刷新页面后才起作用。
我尝试在我的组件onInit方法中实现setTimeout,以及加载ngAfterViewInit和ngOnInit方法中的选项卡,但无济于事。
提前谢谢!
答案 0 :(得分:1)
$( document ).ready()仅运行一次。引用官方文档:
$(document).ready()中包含的代码只有在页面文档对象模型(DOM)准备好执行JavaScript代码时才会运行。
Angular Applications是Single Page Applications。这意味着当您使用Angular Router更改应用程序中的组件时,页面不会刷新,只会动态更改内容。
您看到的行为是因为您最初将应用程序打开到其默认页面,调用了$(document).ready()
函数,但此时,您的语义元素不在DOM中。 ready()
函数执行,无法找到您的元素,因此不会使用这些设置初始化它们。当您路由到组件时,不会再次调用$(document).ready()
,因为页面未刷新。仅更改<router-outlet>
指令内的内容。所以从本质上讲,你的语义元素被添加到DOM BUT,因为$(document).ready()
将不会执行,它们不会被所需的行为初始化。然而,当您在路由组件上刷新页面时,$(document).ready()
IS 被调用,这次DOM中的元素 ARE (因为当Angular初始化时,它确定你在哪个组件基于URL),这就是初始化代码正确定位它们的原因,你可以看到预期的行为。
为避免此问题,我建议您在ngOnInit
函数中移动初始化代码。
export class RoutedComponent implements OnInit {
ngOnInit() {
$('.ui.dropdown').dropdown();
$('.top.menu .item').tab();
$('.tabular.menu .item').tab();
}
}
这样,无论何时您的组件路由,您的初始化代码都将被执行。 ngOnInit
是lifecycle hook,每次实例化组件时都会调用它。