Eccezione Angular2: impossibile associare 'routerLink' poiché non è una proprietà nativa nota


277

Ovviamente la versione beta di Angular2 è più recente che nuova, quindi non ci sono molte informazioni là fuori, ma sto provando a fare quello che penso sia un routing abbastanza semplice.

L'hacking con il codice di avvio rapido e altri frammenti dal sito Web https://angular.io ha portato alla seguente struttura di file:

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

Con i file popolati come segue:

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 { }

instradamento-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 { }

Il tentativo di eseguire questo codice produce l'errore:

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

Ho trovato un problema vagamente correlato qui; direttive router-link infrante dopo l'aggiornamento a angular2.0.0-beta.0 . Tuttavia, l '"esempio funzionante" in una delle risposte si basa sul codice pre-beta, che potrebbe comunque funzionare, ma vorrei sapere perché il codice che ho creato non funziona.

Eventuali puntatori saranno ricevuti con gratitudine!


4
L'altra questione ha qualcosa di diverso: directives: [ROUTER_DIRECTIVES].
Eric Martinez,

1
Ricevo lo stesso errore anche con ROUTER_DIRECTIVES. @Component({selector: "app"}) @View({templateUrl: "app.html", directives: [ROUTER_DIRECTIVES, RouterLink]})
phil

8
Con l'aggiunta directives: [ROUTER_DIRECTIVES]e la modifica da [router-link] a [routerLink] non ricevo più l'errore.
phil

Risposte:


392

> = RC.5

importare la RouterModule Vedi anche 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

Manca il tuo codice

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

Non puoi usare direttive come routerLinko router-outletsenza farle conoscere al tuo componente.

Mentre i nomi delle direttive sono stati cambiati per far distinzione tra maiuscole e minuscole in Angular2, gli elementi usano ancora -nel nome come <router-outlet>essere compatibili con le specifiche dei componenti web che richiedono un -nome in nome di elementi personalizzati.

registrarsi a livello globale

Per rendere ROUTER_DIRECTIVESdisponibile a livello globale, aggiungere questo provider a bootstrap(...):

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

quindi non è più necessario aggiungere ROUTER_DIRECTIVESad ogni componente.


1
sì, puoi anche assegnare più direttive al momento del bootstrap della tua app in questo modo: -provide(PLATFORM_DIRECTIVES, {useValue: [ROUTER_DIRECTIVES, FORM_DIRECTIVES, ETC...], multi: true})
Pardeep Jain

1
Esatto, ma FORM_DIRECTIVESsono già inclusi PLATFORM_DIRECTIVESdi default.
Günter Zöchbauer,

2
È stato fantastico, grazie. L'ho trovato utile anche quando ho cercato di mettere tutto insieme: stackoverflow.com/questions/34391790/…
Jeff

Forse una domanda stupida qui, ma cos'è RC.1, RC.2 qui? Sto usando angolare 2.1.2, quale RC è?
Jian Chen,

1
@AlexanderMills perché i vecchi andwers ti spaventano? Le vecchie risposte sono testate in battaglia e quindi molto affidabili; p
Günter Zöchbauer,

116

Per le persone che lo trovano quando tentano di eseguire test perché tramite npm testo ng testusando Karma o qualsiasi altra cosa. Il tuo modulo .spec necessita di una speciale importazione di test del router per poter essere costruito.

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

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

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


2
Questa è una grande cattura! Il mio progetto non ha avuto problemi con il normale funzionamento, è stato nel specfile che ho dovuto aggiungere questo. Grazie @raykrow!
kbpontius,

1
Confermato di funzionare anche in 4 angolare. Grazie per questo!
JCisar,

Questa deve essere la risposta accettata, la risposta accettata è sbagliata, perché durante l'importazione RouterModule, è necessario chiamare forRootper soddisfare il modulo e quindi è necessario fornire il BASE_HREFe ...
Milad

1
Hai idea se questo è diverso per Angular 5+? Ricevo l'errore simile Can't bind to 'active' since it isn't a known property of 'a'.in molti dei miei test unitari e ho importato RouterTestingModule.
Stuart Updegrave

25

Avvertenza quando si codifica con Visual Studio (2013)

Ho perso 4 o 5 ore nel tentativo di eseguire il debug di questo errore. Ho provato tutte le soluzioni che ho trovato su StackOverflow dalla lettera e ho ancora ricevuto questo errore:Can't bind to 'routerlink' since it isn't a known native property

Attenzione, Visual Studio ha la brutta abitudine di formattare automaticamente il testo quando si copia / incolla il codice. Ho sempre avuto una piccola regolazione istantanea da VS13 (la custodia del cammello scompare).

Questo:

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

diventa:

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

È una piccola differenza, ma abbastanza per innescare l'errore. La parte più brutta è che questa piccola differenza continuava a evitare la mia attenzione ogni volta che copiavo e incollavo. Per puro caso, ho visto questa piccola differenza e l'ho risolta.


4
Grazie, avresti potuto menzionare la differenza tra "routerlink" e "routerLink". Angular 2 si aspetta che sia presente "routerLink" ma trova "routerlink"
Narendran Solai Sridharan,

Grazie, per qualche motivo, alcuni tutorial hanno usato "router-link" con un trattino in mezzo. Ma routerLink è la versione corretta.
windmaomao,

Lo stesso succede con webpack e html-minifier, ma solo in produzione. aggiungi caseSensitive: fedele alle opzioni di html-loader, vedi: github.com/SamanthaAdrichem/webpack-3.9.1-splitted-config-an‌ gular per una configurazione angolare di lavoro 5 + webpack 3.9
Samantha Adrichem

12

Per> = V5

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

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

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

componente:

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

Per <V5

Inoltre può usare RouterLinkcome directivesie. directives: [RouterLink]. quello ha funzionato per me

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},
])

Non credo che questo si applichi più (Angular 5) ecc.
Alexander Mills,

10

In generale, ogni volta che si verifica un errore simile Can't bind to 'xxx' since it isn't a known native property, la causa più probabile è dimenticare di specificare un componente o una direttiva (o una costante che contiene il componente o la direttiva) nella directivesmatrice dei metadati. Questo è il caso qui.

Dal momento che non hai specificato RouterLinko la costante ROUTER_DIRECTIVES- che contiene quanto segue :

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

- directivesnell'array, quindi quando Angular analizza

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

non conosce la direttiva RouterLink (che utilizza il selettore di attributirouterLink ). Poiché Angular sa qual è l' aelemento, presuppone che [routerLink]="..."sia un'associazione di proprietà per l' aelemento. Ma poi scopre che routerLinknon è una proprietà nativa di aelementi, quindi genera l'eccezione sulla proprietà sconosciuta.


Non mi è mai piaciuta molto l' ambiguità della sintassi . Vale a dire, considera

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

Solo guardando l'HTML non possiamo dire se lo whatIsThissia

  • una proprietà nativa di something
  • un selettore di attributi di una direttiva
  • una proprietà di input di something

Dobbiamo sapere quali directives: [...]sono specificati nei metadati del componente / direttiva per interpretare mentalmente l'HTML. E quando dimentichiamo di inserire qualcosa directivesnell'array, sento che questa ambiguità rende un po 'più difficile il debug.


7

Hai nel tuo modulo

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

devi esportare il modulo RouteModule

esempio:

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

per poter accedere alle funzionalità per tutti coloro che importano questo modulo.


5

Ho provato tutti i metodi, che sono menzionati sopra, ma nessun metodo funziona per me. Finalmente ho ottenuto la soluzione per il problema sopra e funziona per me.

Ho provato questo metodo:

In HTML:

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

Nel file TS:

aboutPageLoad() {
    this.router.navigate(['/about']);
}

4

Nel mio caso ho importato il RouterModule nel modulo App ma non importato nel mio modulo funzionalità. Dopo aver importato il modulo router nel mio EventModule, l'errore scompare.

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 {

 }

3

Se viene visualizzato questo errore durante il test dell'unità, scrivere questo.

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

0

Apprezzo molto la risposta di @ raykrow quando si ha questo problema solo in un file di prova! È lì che l'ho incontrato.

Poiché è spesso utile avere un altro modo di fare qualcosa come backup, volevo menzionare questa tecnica che funziona anche (invece di importare RouterTestingModule):

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

(In genere, si utilizza routerLinksu un <a>elemento ma si regola il selettore di conseguenza per altri componenti.)

Il secondo motivo per cui ho voluto menzionare questa soluzione alternativa è che, sebbene mi sia servito bene in numerosi file di specifiche, ho riscontrato un problema con esso in un caso:

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

Non riuscivo a capire come questo e il mio ButtonComponentstessero usando lo stesso selettore, quindi la ricerca di un approccio alternativo mi ha portato qui alla soluzione di @ raykrow.


0

Se si utilizzano moduli condivisi, è sufficiente aggiungere RouterModule a un modulo in cui viene dichiarato il componente e non dimenticare di aggiungere <router-outlet></router-outlet>

Riferimento da qui RouterLink non funziona


-4

La mia soluzione è semplice Sto usando [href] invece di [routerLink]. Ho provato tutte le soluzioni per [routerLink]. Nessuno di loro funziona nel mio caso.

Ecco la mia soluzione:

<a [href]="getPlanUrl()" target="_blank">My Plan Name</a>

Quindi scrivere la getPlanUrlfunzione nel file TS.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.