web-dev-qa-db-fra.com

Exception Angular2: impossible de se lier à 'routerLink' car ce n'est pas une propriété native connue

De toute évidence, la version bêta d’Angular2 est plus récente que la nouvelle, il n’ya donc pas beaucoup d’informations disponibles, mais j’essaie de faire ce que j’estime être un routage assez basique. 

Le piratage avec le code de démarrage rapide et d'autres extraits du site Web https://angular.io a abouti à la structure de fichier suivante:

angular-testapp/
    app/
        app.component.ts
        boot.ts
        routing-test.component.ts
    index.html

Avec les fichiers en cours de remplissage comme suit:

index.html

<html>

  <head>
    <base href="/">
    <title>Angular 2 QuickStart</title>
    <link href="../css/bootstrap.css" rel="stylesheet">

    <!-- 1. Load libraries -->
    <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.js"></script>
    <script src="node_modules/angular2/bundles/angular2.dev.js"></script>
    <script src="node_modules/angular2/bundles/router.dev.js"></script>

    <!-- 2. Configure SystemJS -->
    <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/boot')
            .then(null, console.error.bind(console));
    </script>

  </head>

  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>

</html>

boot.ts

import {bootstrap}    from 'angular2/platform/browser'
import {ROUTER_PROVIDERS} from 'angular2/router';

import {AppComponent} from './app.component'

bootstrap(AppComponent, [
    ROUTER_PROVIDERS
]);

app.component.ts

import {Component} from 'angular2/core';
import {RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, LocationStrategy, HashLocationStrategy} from 'angular2/router';

import {RoutingTestComponent} from './routing-test.component';

@Component({
    selector: 'my-app',
    template: `
        <h1>Component Router</h1>
        <a [routerLink]="['RoutingTest']">Routing Test</a>
        <router-outlet></router-outlet>
        `
})

@RouteConfig([
    {path:'/routing-test', name: 'RoutingTest', component: RoutingTestComponent, useAsDefault: true},
])

export class AppComponent { }

routing-test.component.ts

import {Component} from 'angular2/core';
import {Router} from 'angular2/router';

@Component({
    template: `
        <h2>Routing Test</h2>
        <p>Interesting stuff goes here!</p>
        `
})
export class RoutingTestComponent { }

Tenter d'exécuter ce code génère l'erreur:

EXCEPTION: Template parse errors:
Can't bind to 'routerLink' since it isn't a known native property ("
        <h1>Component Router</h1>
        <a [ERROR ->][routerLink]="['RoutingTest']">Routing Test</a>
        <router-outlet></router-outlet>
        "): AppComponent@2:11

J'ai trouvé un problème vaguement lié ici; (directives de liaison de routeur brisées après la mise à niveau vers angular2.0.0-beta.0 }. Cependant, "l'exemple de travail" dans l'une des réponses est basé sur du code pré-bêta - qui peut toujours fonctionner, mais j'aimerais savoir pourquoi le code que j'ai créé ne fonctionne pas.

Tous les pointeurs seraient reçus avec reconnaissance!

219
Lester Burnham

> = RC.5

importer la RouterModule Voir aussi https://angular.io/guide/router

@NgModule({ 
  imports: [RouterModule],
  ...
})

> = RC.2

app.routes.ts

import { provideRouter, RouterConfig } from '@angular/router';

export const routes: RouterConfig = [
  ...
];

export const APP_ROUTER_PROVIDERS = [provideRouter(routes)];

main.ts

import { bootstrap } from '@angular/platform-browser-dynamic';
import { APP_ROUTER_PROVIDERS } from './app.routes';

bootstrap(AppComponent, [APP_ROUTER_PROVIDERS]);

<= RC.1

Votre code est manquant 

  @Component({
    ...
    directives: [ROUTER_DIRECTIVES],
    ...)}

Vous ne pouvez pas utiliser de directives telles que routerLink ou router-outlet sans les communiquer à votre composant. 

Bien que les noms de directive aient été modifiés pour tenir compte de la casse dans Angular2, les éléments utilisent toujours - dans le nom tel que <router-outlet> pour être compatible avec la spécification de composants Web qui requiert un - dans le nom des éléments personnalisés.

enregistrer globalement

Pour rendre ROUTER_DIRECTIVES globalement disponible, ajoutez ce fournisseur à bootstrap(...):

provide(PLATFORM_DIRECTIVES, {useValue: [ROUTER_DIRECTIVES], multi: true})

alors il n'est plus nécessaire d'ajouter ROUTER_DIRECTIVES à chaque composant.

329
Günter Zöchbauer

Pour les personnes qui trouvent cela en essayant d'exécuter des tests parce que via npm test ou ng test en utilisant Karma ou autre. Votre module .spec nécessite une importation de test de routeur spéciale pour pouvoir être construit.

import { RouterTestingModule } from '@angular/router/testing';

  TestBed.configureTestingModule({
    imports: [RouterTestingModule],
    declarations: [AppComponent],
  });

http://www.kirjai.com/ng2-component-testing-routerlink-routeroutlet/

90
rayepps

Mot d'avertissement lors du codage avec Visual Studio (2013)

J'ai perdu 4 à 5 heures à essayer de corriger cette erreur. J'ai essayé toutes les solutions trouvées sur stackoverflow par lettre et j'ai toujours cette erreur: Can't bind to 'routerlink' since it isn't a known native property

Sachez que Visual Studio a la vilaine habitude de formater automatiquement du texte lorsque vous copiez/collez du code. J'ai toujours eu un petit ajustement instantané de VS13 (l'affaire camel disparaît).

Ce:

<div>
    <a [routerLink]="['/catalog']">Catalog</a>
    <a [routerLink]="['/summary']">Summary</a>
</div>

Devient:

<div>
    <a [routerlink]="['/catalog']">Catalog</a>
    <a [routerlink]="['/summary']">Summary</a>
</div>

C'est une petite différence, mais suffisante pour déclencher l'erreur. La partie la plus moche est que cette petite différence évitait simplement d’éviter mon attention chaque fois que je copiais et collais. Par pure chance, j'ai vu cette petite différence et l'ai résolue.

22
Adrian Moisa

Pour> = V5

import { RouterModule, Routes } from '@angular/router';

const appRoutes: Routes = [
  {path:'routing-test', component: RoutingTestComponent}
];

@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes)
    // other imports here
  ]
})

composant:

@Component({
    selector: 'my-app',
    template: `
        <h1>Component Router</h1>
        <a routerLink="/routing-test" routerLinkActive="active">Routing Test</a>
        <router-outlet></router-outlet>
        `
})

Pour <V5

Peut aussi utiliser RouterLink comme directives c'est-à-dire. directives: [RouterLink]. cela a fonctionné pour moi

import {Router, RouteParams, RouterLink} from 'angular2/router';

@Component({
    selector: 'my-app',
    directives: [RouterLink],
    template: `
        <h1>Component Router</h1>
        <a [routerLink]="['RoutingTest']">Routing Test</a>
        <router-outlet></router-outlet>
        `
})

@RouteConfig([
    {path:'/routing-test', name: 'RoutingTest', component: RoutingTestComponent, useAsDefault: true},
])
9
Shaishab Roy

En général, chaque fois que vous obtenez une erreur telle que Can't bind to 'xxx' since it isn't a known native property, la cause la plus probable consiste à oublier de spécifier un composant ou une directive (ou une constante contenant le composant ou la directive) dans le tableau de métadonnées directives. Tel est le cas ici.

Puisque vous n'avez pas spécifié RouterLink ou la constante ROUTER_DIRECTIVES - qui contient les éléments suivants :

export const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, 
  RouterLinkActive];

- dans le tableau directives, puis quand analyse angulaire

<a [routerLink]="['RoutingTest']">Routing Test</a>

il ne connaît pas la directive directive RouterLink (qui utilise le sélecteur attributrouterLink). Comme Angular sait ce qu'est l'élément a, il suppose que [routerLink]="..." est une liaison property pour l'élément a. Mais il découvre ensuite que routerLink n'est pas une propriété native d'éléments a, d'où il lève l'exception à propos de la propriété unknown.


Je n'ai jamais vraiment aimé le ambiguïté de la syntaxe . C'est-à-dire considérer

<something [whatIsThis]="..." ...>

En regardant le code HTML, nous ne pouvons pas savoir si whatIsThis est 

  • une propriété native de something
  • sélecteur d'attribut d'une directive
  • une propriété d'entrée de something

Nous devons savoir quels directives: [...] sont spécifiés dans les métadonnées du composant/directive afin d'interpréter mentalement le code HTML. Et lorsque nous oublions de placer quelque chose dans le tableau directives, j’ai le sentiment que cette ambiguïté rend le débogage un peu plus difficile.

8
Mark Rajcok

Vous avez dans votre module

import {Routes, RouterModule} from '@angular/router';

vous devez exporter le module RouteModule

exemple:

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})

pouvoir accéder aux fonctionnalités pour tous ceux qui importent ce module.

7
alehn96

Dans mon cas, j'ai importé le module RouterModule in App, mais pas dans mon module de fonctions. Après avoir importé le module de routeur dans mon EventModule, l'erreur disparaît.

import {NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import {EventListComponent} from './EventList.Component';
import {EventThumbnailComponent} from './EventThumbnail.Component';
import { EventService } from './shared/Event.Service'
import {ToastrService} from '../shared/toastr.service';
import {EventDetailsComponent} from './event-details/event.details.component';
import { RouterModule } from "@angular/router";
@NgModule({
  imports:[BrowserModule,RouterModule],
  declarations:[EventThumbnailComponent,EventListComponent,EventDetailsComponent],
  exports: [EventThumbnailComponent,EventListComponent,EventDetailsComponent],
   providers: [EventService,ToastrService]
})
export class EventModule {

 }
4
Code-EZ

J'ai essayé toutes les méthodes, qui sont mentionnées ci-dessus.Mais aucune méthode ne fonctionne pour moi. Enfin, j'ai la solution pour le problème ci-dessus et cela fonctionne pour moi. 

J'ai essayé cette méthode:

En HTML:

<li><a (click)= "aboutPageLoad()"  routerLinkActive="active">About</a></li>

Dans le fichier TS:

aboutPageLoad() {
    this.router.navigate(['/about']);
}
2
Sunil Kumar K K

Si vous obtenez cette erreur lors des tests unitaires, écrivez ceci.

import { RouterTestingModule } from '@angular/router/testing';
beforeEach(async(() => {
  TestBed.configureTestingModule({
   imports: [RouterTestingModule],
   declarations: [AppComponent],
 });
}));
0
Deeksha Bilochi

Si vous utilisez des modules partagés, ajoutez simplement RouterModule à un module dans lequel votre composant est déclaré et n'oubliez pas d'ajouter <router-outlet></router-outlet>

Référencé à partir d'ici RouterLink ne fonctionne pas

0
Yevheniy Potupa

J'apprécie beaucoup la réponse de @ raykrow quand on n'a ce problème que dans un fichier test! C'est là que je l'ai rencontré.

Comme il est souvent utile d’avoir une autre façon de faire une sauvegarde, je voulais mentionner cette technique qui marche aussi (au lieu d’importer RouterTestingModule):

import { MockComponent } from 'ng2-mock-component';
. . .
TestBed.configureTestingModule({
  declarations: [
    MockComponent({
      selector: 'a',
      inputs: [ 'routerLink', 'routerLinkActiveOptions' ]
    }),
    . . .
  ]

(En règle générale, on utilise routerLink sur un élément <a> mais on ajuste le sélecteur en conséquence pour les autres composants.)

La deuxième raison pour laquelle je voulais mentionner cette solution de rechange est que, même si elle m'a bien servi dans un certain nombre de fichiers de spécification, elle a rencontré un problème dans un cas:

Error: Template parse errors:
    More than one component matched on this element.
    Make sure that only one component's selector can match a given element.
    Conflicting components: ButtonComponent,Mock

Je n'arrivais pas à comprendre comment cette maquette et ma ButtonComponent utilisaient le même sélecteur. La recherche d'une autre approche m'a donc conduit à la solution de @ raykrow.

0
Michael Sorens