【问题标题】:Angular 2 RC1 - Cannot find default outletAngular 2 RC1 - 找不到默认插座
【发布时间】:2016-10-09 13:51:43
【问题描述】:

我正在尝试从 Angular 2 beta.17 升级到 Angular 2 RC1,并且在单击菜单 (html) 中的 routeLink 时遇到以下异常,请任何想法对我做错的事情有所帮助。

browser_adapter.ts:78 Error: Uncaught (in promise): Cannot find default outlet
    at resolvePromise (zone.js:538)
    at zone.js:574
    at ZoneDelegate.invokeTask (zone.js:356)
    at Object.NgZoneImpl.inner.inner.fork.onInvokeTask (ng_zone_impl.ts:56)
    at ZoneDelegate.invokeTask (zone.js:355)
    at Zone.runTask (zone.js:256)
    at drainMicroTaskQueue (zone.js:474)
    at XMLHttpRequest.ZoneTask.invoke (zone.js:426)

请看下面我的代码...

应用:

import {Component} from "@angular/core";
import {Routes} from "@angular/router";
import {LoggedInRouterOutlet} from "../../common/directives/logged-in-router-outlet.directive";
import {HeaderComponent} from "../../common/components/header.component";
import {ErrorComponent} from "../../common/components/error.component";
import {AlertComponent} from "../../common/components/alert.component";
import {MenuComponent} from "../../common/components/menu.component";
import {FooterComponent} from "../../common/components/footer.component";
import {router} from "../../routes/routes";

@Component({
  selector: 'my-app',
  directives: [HeaderComponent, ErrorComponent, AlertComponent, MenuComponent, FooterComponent, LoggedInRouterOutlet],
  templateUrl: 'modules/app/components/app.html'
})
@Routes(router.config)
export class AppComponent {
}

应用程序(html):

<header></header>

<error></error>

<alert></alert>

<menu></menu>

<div class="section">
    <logged-in-router-outlet></logged-in-router-outlet>
</div>

<footer></footer>

路线:

import {HomeComponent} from '../home/components/home.component';
import {LoginComponent} from '../login/components/login.component';
import {CustomerSearchComponent} from '../customer/components/search.component';

export const router = {
    // confirm , useAsDefault: true does not work anymore
    config: [
        {path: '/home', component: HomeComponent, name: 'Home'},
        {path: '/login', component: LoginComponent, name: 'Login'},
        {path: '/customer_search', component: CustomerSearchComponent, name: 'CustomerSearch'},
        {path: '*', component: HomeComponent}
    ]
};

引导程序:

import {ROUTER_PROVIDERS} from "@angular/router";
import {HTTP_PROVIDERS} from "@angular/http";
import {bootstrap} from "@angular/platform-browser-dynamic";
import {enableProdMode} from "@angular/core";

import {AppComponent} from "../app/components/app.component";

import {AuthenticationService} from "../common/services/authentication.service";
import {RequestService} from "../common/services/request.service";
import {NotificationService} from "../common/services/notification.service";
import {Base64Service} from "../common/services/base64.service";
import {ValidationService} from "../common/services/validation.service";

enableProdMode(); 

bootstrap(AppComponent,
  [
    ROUTER_PROVIDERS,
    HTTP_PROVIDERS,
    AuthenticationService,
    RequestService,
    NotificationService,
    Base64Service,
    ValidationService
  ]);

路由器(指令):

import {ElementRef, DynamicComponentLoader, AttributeMetadata, Directive} from '@angular/core';
import {Router} from '@angular/router';
import {AuthenticationService} from '../services/authentication.service';
import {RouterOutlet} from '@angular/router/src/directives/router_outlet'; 

@Directive({
  selector: 'logged-in-router-outlet'
})
export class LoggedInRouterOutlet extends RouterOutlet {
  publicRoutes = [
    'home', 'login'
  ];

  static get parameters() {
    return [[ElementRef], [DynamicComponentLoader], [Router], [new AttributeMetadata('name'), String], [AuthenticationService]];
  }

  constructor(elementRef, componentLoader, parentRouter, name, authenticationService) {
    super(elementRef, componentLoader, parentRouter, name);

    this.parentRouter = parentRouter;
    this.authenticationService = authenticationService;
  }

  activate(instruction) {
    if (this._canActivate(instruction.urlPath)) {
      return super.activate(instruction);
    }

    this.parentRouter.navigate(['login']);
  }

  _canActivate(url) {
    return this.publicRoutes.indexOf(url) !== -1 || this.authenticationService.isLoggedIn();
  }
}

菜单:

import {Component} from "@angular/core";
import {ROUTER_DIRECTIVES, Router} from "@angular/router";
import {AuthenticationService} from "../services/authentication.service";

@Component({
  selector: 'menu',
  directives: [ROUTER_DIRECTIVES],
  templateUrl: 'modules/common/components/menu.html'
})
export class MenuComponent {
  router;

  static get parameters() {
    return [[Router],[AuthenticationService]];
  }

  constructor(router, authenticationService) {
    this.router = router;
    this.authenticationService = authenticationService;
  }

  isLoggedIn() {
    return this.authenticationService.getLoggedIn();
  }

  logout() {
    this.authenticationService.logout();
    this.router.navigate(['/home']);
    return false;
  }
}

菜单(html):

<div class="navbar navbar-default">
    <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#menu-navbar-collapse">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" [routerLink]="['home']">Home</a>
    </div>

    <div class="collapse navbar-collapse" id="menu-navbar-collapse" data-ng-controller="MenuController">
        <ul class="nav navbar-nav">
            <li class="dropdown">
                <a class="dropdown-toggle" data-toggle="dropdown">Customer <span class="caret"></span></a>
                <ul class="dropdown-menu">
                    <li><a [routerLink]="['customer_search']">Search</a></li>
                </ul>
            </li>
        </ul>
        <ul class="nav navbar-nav navbar-right" *ngIf="!(isLoggedIn() | async)">
            <li class="dropdown">
                <a class="dropdown-toggle" data-toggle="dropdown">Login or Register <span class="caret"></span></a>
                <ul class="dropdown-menu">
                    <li><a [routerLink]="['login']"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
                </ul>
            </li>
        </ul>
        <ul class="nav navbar-nav navbar-right" *ngIf="(isLoggedIn() | async)">
            <li class="dropdown">
                <a class="dropdown-toggle" data-toggle="dropdown">My Account <b class="caret"></b></a>
                <ul class="dropdown-menu">
                    <li><a href="#" (click)="logout()">Logout</a></li>
                </ul>
            </li>
        </ul>
    </div>
</div>

根据下面提供的答案更新。

例外:

TypeError: this._parentRouter.registerPrimaryOutlet is not a function
    at LoggedInRouterOutlet.RouterOutlet (router_outlet.ts:46)
    at new LoggedInRouterOutlet (logged-in-router-outlet.directive.js:108)
    at DebugAppView._View_AppComponent0.createInternal (AppComponent.template.js:61)
    at DebugAppView.AppView.create (view.ts:110)
    at DebugAppView.create (view.ts:315)
    at DebugAppView._View_AppComponent_Host0.createInternal (AppComponent_Host.template.js:17)
    at DebugAppView.AppView.create (view.ts:110)
    at DebugAppView.create (view.ts:315)
    at ComponentFactory.create (component_factory.ts:96)
    at eval (application_ref.ts:359)

路由器(指令):

import {ElementRef, DynamicComponentLoader, AttributeMetadata, Directive} from '@angular/core';
import {Router} from '@angular/router';
import {AuthenticationService} from '../services/authentication.service';
import {RouterOutlet} from '@angular/router-deprecated'; // TODO: temp replace with rc2 as that exports it

@Directive({
  selector: 'router-outlet'
})
export class LoggedInRouterOutlet extends RouterOutlet {
  publicRoutes = [
    'home', 'login'
  ];

  static get parameters() {
    return [[ElementRef], [DynamicComponentLoader], [Router], [new AttributeMetadata('name'), String], [AuthenticationService]];
  }

  constructor(elementRef, componentLoader, parentRouter, name, authenticationService) {
    super(elementRef, componentLoader, parentRouter, name);

    this.parentRouter = parentRouter;
    this.authenticationService = authenticationService;
  }

  activate(instruction) {
    if (this._canActivate(instruction.urlPath)) {
      return super.activate(instruction);
    }

    this.parentRouter.navigate(['login']);
  }

  _canActivate(url) {
    return this.publicRoutes.indexOf(url) !== -1 || this.authenticationService.isLoggedIn();
  }
}

应用程序(html):

<header></header>

<error></error>

<alert></alert>

<menu></menu>

<div class="section">
    <router-outlet></router-outlet>
</div>

<footer></footer>

【问题讨论】:

    标签: javascript html angularjs angular


    【解决方案1】:

    @angular/router 3.0.0-alpha.6 也有同样的问题。我以这个 Plnkr 为例:http://plnkr.co/edit/ER0tf8fpGHZiuVWB7Q07.

    当组件使用

    从@angular/router 导入 ROUTER_DIRECTIVES 时,我的错误消失了
    <router-outlet> 
    

    在模板中。像这样:

    directives: [ROUTER_DIRECTIVES]. 
    

    请检查 Plnkr。尤其是 app.component.ts 和 app/crisis-center/crisis-center.component.ts。两者都导入 ROUTER_DIRECTIVES。

    【讨论】:

    • 非常感谢,我会看看是否应用相同的方法解决了我的问题。
    • 没问题,希望对你有帮助!
    【解决方案2】:

    听起来像这个问题https://github.com/angular/angular/issues/8427

    选择器需要和RC.1中原来的路由器出口selector: 'router-outlet'一样

    提示

    @angular/router 也已弃用。一个新的(或重新设计的)路由器正在进行中。目前,在新的新路由器推出之前,最好坚持使用@angular/router-deprecated

    【讨论】:

    • 非常感谢您的回复,我同意这看起来确实是同一个问题。当我做出建议的更改时,我现在得到一个单独的错误。 TypeError: this._parentRouter.registerPrimaryOutlet 不是函数,请查看我上面更新的问题以查看我所做的更改和错误的堆栈跟踪,如果您对此有任何想法,我们将不胜感激,感谢您的宝贵时间。跨度>
    • 我没有其他想法。一个新的路由器又一次即将发货。我不确定在当前路由器上花费大量时间是否是个好主意。
    【解决方案3】:

    似乎RC1路由器也被弃用了。

    一个多月前,我们在 ng-conf 推出了一款新路由器。 我们希望这将最终解决未解决的路由问题 我们的第一个设计。

    事实证明,路由很难。

    我们很高兴收到 ng-conf 的许多人关于 这个新设计,所以我们宣布版本 3.0.0-alpha.3 @angular/router 并且正在弃用版本 2。您应该开始使用 立即使用此路由器。

    http://angularjs.blogspot.de/2016/06/improvements-coming-for-routing-in.html

    他们建议将路由升级到新版本并为其提供一些 plunkr

    从查看这个 plunker 开始,继续关注更多关于 这个路由器,以及即将推出的 Angular 2 RC2。

    似乎 RC1 和 3.0.0-alpha.3 版本都不是稳定的。因此,由您决定哪个版本使用 @angular/router-deprecated 或版本 3.0.0-alpha.3。但是 RC1 甚至没有很多文档,我不建议使用。你也可以看看ui-router-ng2

    【讨论】:

    • 我想我将不得不推迟到新路由器发布,感谢您的解释和时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多