【问题标题】:Angular Routing selector "app-home" did not match element角度路由选择器“app-home”与元素不匹配
【发布时间】:2021-04-07 23:08:15
【问题描述】:

我想防止我的初始组件被加载两次。我正在尝试使用默认/空组件来避免使用 AppComponent 加载 AppComponent 空组件将是起点,在用户命令中加载其他组件。

我仍在研究 Angular Routing,但据我了解,路由器出口在模块中动态加载,默认情况下总是从 AppComponent 开始?

我认为设置一个空的 Homecomponent 会破坏 AppComponent-loop

我做错了什么? 这是与问题相关的所有代码吗?

我的索引.html

<!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="utf-8" />          
      <base href="/" />
      <meta name="viewport" content="width=device-width, initial-scale=1" />   
    </head>
    <body>
      <app-root>
         Loading...
      </app-root>
    </body>
</html>

我的 app.component.html

<app-nav-menu></app-nav-menu>    //navigation that is always shown
<router-outlet></router-outlet>  

应用路线:

const routes: Routes = [
  { path: 'home', component: HomeComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' }
];
@NgModule({
  imports: [
    RouterModule.forRoot(routes),
    HomeModule,  
    AccountModule,
    OtherModules
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

我的 home.html 只是一个空的 html 文件

我的家庭模块

@NgModule({
  declarations: [    
  ],
  imports: [
    CommonModule,     
    RouterModule.forChild([  
       { path: 'feed', loadChildren: () => import('./../home/feed/feed.module')
                                .then(x => x.FeedModule)},

       { path: 'search', loadChildren: () => import('./../home/searchresults/search.module')
                                .then(x => x.SearchModule)}  

    ]),
    SharedModule,
    OtherModules    
  ],
  exports: [
    CommonModule,
    RouterModule,    
    SharedModule,
    OtherModules     
  ],
  providers: [
    LoginService
  ]
})
export class HomeModule { }

应用模块:

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,     
    FirstLoadedComponent,    
    AuthCallbackComponent    
  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
    AppRoutingModule,
    SharedModule,
    HttpClientModule,
    ReactiveFormsModule,
    FormsModule,
    CoreModule,
    OtherModules
  ],
  exports: [
  ...
  ],
  providers: [
  ...
  ],
  bootstrap: [
    //HomeComponent //gives error
    //FirstLoadedComponent //gives error
    AppComponent //triggers a <app-root>-inception resulting in double load of first component
  ],
  entryComponents: [
  ...
  ]
})
export class AppModule {

}

当我在 AppModule 中引导 AppComponent 时,它会触发第二个 AppModule,因此第一个加载的组件会显示两次。

当我想引导 HomeComponent(空 html)或第一个加载的组件时,我收到错误:

The selector "app-home" did not match any elements at DefaultDomRenderer2.selectRootElement 
(platform-browser.js:661)

当我在根 AppModule 中声明 HomeComponent(使用选择器 app-home)时,这怎么可能? 我是否在某处用错误的逻辑覆盖了好的逻辑?级联可能有点混乱。

*编辑:我没有同时引导所有 3 个组件,只是一个一个地引导并在评论中添加行为是什么。

感谢您的意见

【问题讨论】:

标签: angular angular-routing angular-module


【解决方案1】:

让我们从声明开始

我仍在研究 Angular Routing,但据我了解,路由器出口会动态加载模块,默认情况下总是从 AppComponent 开始?

这是部分正确的。在您的 AppModule 中,您有各种数组

声明——这个应用程序的唯一组件。

imports——导入 BrowserModule 以提供特定于浏览器的服务,例如 DOM 渲染、清理和定位。

providers——服务提供商。

bootstrap——Angular 创建并插入到 index.html 宿主网页中的根组件。

基本上你在引导数组中加载的任何组件都会被加载,

接下来需要注意的是,只要你不在 declarations 数组中声明组件,Angular 就无法知道该组件并会抛出错误

因此,为了解决您的多重加载问题,请从 boostrap 数组中移除额外的组件

bootstrap: [AppComponent],

现在,如果您不需要加载 HomeComponent,您还需要将其作为模块延迟加载

const routes: Routes = [
  {  
     path: 'home', 
     loadChildren: () => import('home/home.module.ts').then(
     m => m.HomeModule
    ) 
  },
  { path: '', redirectTo: 'home', pathMatch: 'full' }
];

现在您需要从AppModule 的声明数组中删除HomeComponent 并将其添加到HomeModule 的声明数组中

【讨论】:

  • 感谢您的回答和良好的解释。我按照您的指示进行操作,但仍然遇到同样的问题。路由器模块中是否有可能使测试复杂化的缓存?有时,我会得到想要的行为,但前提是我完全重新启动后端、杀死前端、清理缓存并从零重新启动。即便如此也不总是
  • 再次感谢您的良好解释。这让我在别处寻找问题。我的 中有第二个路由器插座。把我弄傻了,但多亏了你的保证,我发现它相当快!谢谢你,祝你有个愉快的夜晚!
  • 很好,很抱歉离线
猜你喜欢
  • 2016-06-09
  • 2016-06-09
  • 1970-01-01
  • 2016-11-24
  • 2018-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多