为啥没有 <app-root> 的其他组件没有出现在 index.html 上?

Posted

技术标签:

【中文标题】为啥没有 <app-root> 的其他组件没有出现在 index.html 上?【英文标题】:Why other components not showing up on index.html without <app-root>?为什么没有 <app-root> 的其他组件没有出现在 index.html 上? 【发布时间】:2020-01-14 22:12:35 【问题描述】:

我刚刚开始学习 Angular 并完成了一些教程。我的项目是由 Angular CLI 生成的。我在创建项目时生成的组件之上生成了一个名为 navbar 的新组件,我试图查看启动时导航栏是否加载到我的 index.html 上。仅当我在 index.html 文件中有两个应用程序时,我的导航栏才会显示,例如:

<body>
  <app-root></app-root>
  <app-navbar></app-navbar>
</body>

如果我像这样从 index.html 中删除 app-root:

<body>
  <app-navbar></app-navbar>
</body>

我的导航栏应用不再显示它。这与 app-root 组件有关吗?是不是因为它是根组件,必须一直包含在 index.html 中?

这是我的代码:

index.html:

<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title></title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>

<body>
  <app-navbar></app-navbar>
</body>

</html>

app.module.ts:

import  BrowserModule  from '@angular/platform-browser';
import  NgModule  from '@angular/core';

import  AppRoutingModule  from './app-routing.module';
import  AppComponent  from './component1/app.component';
import  NavbarComponent  from './navbar/navbar.component';

@NgModule(
  declarations: [
    AppComponent,
    NavbarComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [
    AppComponent,
    NavbarComponent
  ]
)
export class AppModule  

navbar.component.ts:

import  Component, OnInit  from '@angular/core';

@Component(
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
)
export class NavbarComponent 
  constructor() 

  // tslint:disable-next-line: use-lifecycle-interface
  ngOnInit() 

  


【问题讨论】:

【参考方案1】:

您必须将组件选择器放在 app.component.html 中:

<app-navbar></app-navbar>

&lt;app-root&gt; 标签是显示引导组件的位置(默认为 AppComponent)。而且通常您不需要超过 1 个引导组件,因此请从 AppModule 的引导程序中删除 NavbarComponent

在更高层次的视图中,您可以将您的应用程序视为组件树,它的根是 AppComponent,因此 AppComponent 的子级必须放在 app.component.html 中,例如 NavBarComponent 的子级必须是放在navbar.component.html 里面。

【讨论】:

从 AppModule 中的boostrap 中删除 NavbarComponent,我更新了答案 如果不正确,为什么 Angular 团队将引导程序作为一个数组,这里的导航栏只是一个主题组件,所以将它移到外面没有害处,但是来自单个模块的 Angular 应用程序引导程序检查我的答案:)【参考方案2】:

您可以向引导程序添加多个组件,但它们必须来自同一个模块

@NgModule(
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent, NavbarComponent ],
  bootstrap:    [ AppComponent ,NavbarComponent ]
)
export class AppModule  

index.html

<my-app>loading</my-app>
<app-navbar>loading</app-navbar>

来自单个模块的 Angular 应用引导程序,例如此处的 appmodule

main.ts

platformBrowserDynamic().bootstrapModule(AppModule).then(ref => 
  // Ensure Angular destroys itself on hot reloads.
  if (window['ngRef']) 
    window['ngRef'].destroy();
  
  window['ngRef'] = ref;

  // Otherwise, log the boot error
).catch(err => console.error(err));

demo ⚡⚡

【讨论】:

为什么在我从 index.html 中删除 loading 后,导航栏停止显示其内容(“导航栏有效!”),而是显示“正在加载”。跨度> 试试这样bootstrap: [ NavbarComponent , AppComponent ] 为什么要将任何组件添加到引导列表中,angula 会查找该组件选择器并抛出错误,即使任何组件丢失 angular 期望两个组件都存在于 index.htm 中跨度> 所以在你的情况下,在渲染另一个组件之前抛出错误,我想问你为什么要尝试这个为什么不把导航栏放在应用程序组件中并引导应用程序组件 @malbarmavi,例如,如果您需要在主应用程序之外渲染 Angular 组件,例如 ***.com/questions/38526221/…【参考方案3】:

Angular 尝试查找 app-root 标记并抛出您可以在浏览器控制台中看到的错误,如下所示:

错误:选择器“app-root”没有匹配任何元素 在 ha.selectRootElement (main-*.js)

所以渲染崩溃,导航栏不显示

为避免此问题,将带有条件的 ngDoBootstrap 方法添加到根应用模块:

@NgModule(
  declarations: [],
  imports: [BrowserModule, AppRoutingModule],
  providers: [],
  bootstrap: []
)
export class AppModule

  ngDoBootstrap(appRef: ApplicationRef)
  
    if (document.getElementsByTagName('app-root').length > 0)
    
      appRef.bootstrap(AppComponent, 'app-root')
    
    if (document.getElementsByTagName('app-navbar').length > 0)
    
      appRef.bootstrap(NavbarComponent, 'app-navbar')
    
  

【讨论】:

以上是关于为啥没有 <app-root> 的其他组件没有出现在 index.html 上?的主要内容,如果未能解决你的问题,请参考以下文章

更新到角度6后找不到app-root

Angular应用的启动流程

W3C验证器在app-root处的index.html中返回一个错误。

点击a元素显示对应的div,点击其他地方隐藏div或者显示对应div用js控制怎么写?为啥alert()没有输出?

Angular:如何与应用程序组件(应用程序根)共享来自自定义组件的数据

选择器“new-selector”与任何元素都不匹配