Angular2-Ausnahme: Kann nicht an 'routerLink' gebunden werden, da es sich nicht um eine bekannte native Eigenschaft handelt

277

Offensichtlich ist die Beta für Angular2 neuer als neu, daher gibt es nicht viele Informationen, aber ich versuche, das zu tun, was ich für ein ziemlich einfaches Routing halte.

Das Hacken mit dem Schnellstartcode und anderen Ausschnitten von der https: //angular.io-Website hat zu der folgenden Dateistruktur geführt:

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

Die Dateien werden wie folgt gefüllt:

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

Der Versuch, diesen Code auszuführen, führt zu folgendem Fehler:

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

Ich habe hier ein vage verwandtes Problem gefunden; Router-Link-Anweisungen sind nach dem Upgrade auf angle2.0.0-beta.0 fehlerhaft . Das "Arbeitsbeispiel" in einer der Antworten basiert jedoch auf Pre-Beta-Code - der möglicherweise noch funktioniert, aber ich würde gerne wissen, warum der von mir erstellte Code nicht funktioniert.

Alle Hinweise wären dankbar!

Lester Burnham
quelle
4
Die andere Frage hat etwas anderes : directives: [ROUTER_DIRECTIVES].
Eric Martinez
1
Ich erhalte den gleichen Fehler auch mit ROUTER_DIRECTIVES. @Component({selector: "app"}) @View({templateUrl: "app.html", directives: [ROUTER_DIRECTIVES, RouterLink]})
Phil
8
Durch das Hinzufügen directives: [ROUTER_DIRECTIVES]und Wechseln von [Router-Link] zu [Router-Link] wird der Fehler nicht mehr angezeigt.
Phil

Antworten:

392

> = RC.5

Importieren Sie das RouterModule Siehe auch 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

Ihr Code fehlt

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

Sie können keine Direktiven wie routerLinkoder verwendenrouter-outlet ohne sie Ihrer Komponente bekannt zu machen.

Während Direktivennamen in Angular2 so geändert wurden, dass zwischen Groß- und Kleinschreibung unterschieden wird, werden Elemente -im Namen weiterhin verwendet <router-outlet>, um mit der Webkomponentenspezifikation kompatibel zu sein, für die ein -Name im Namen benutzerdefinierter Elemente erforderlich ist .

Registrieren Sie sich global

ROUTER_DIRECTIVESFügen Sie diesen Anbieter hinzu, um ihn global verfügbar zu machen bootstrap(...):

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

Dann ist es nicht mehr erforderlich ROUTER_DIRECTIVES, jeder Komponente etwas hinzuzufügen .

Günter Zöchbauer
quelle
1
Ja, Sie können auch mehrere Anweisungen zum Zeitpunkt des Bootstrapens Ihrer App wie provide(PLATFORM_DIRECTIVES, {useValue: [ROUTER_DIRECTIVES, FORM_DIRECTIVES, ETC...], multi: true})
folgt zuweisen
1
Das ist richtig, aber FORM_DIRECTIVESist enthalten PLATFORM_DIRECTIVESbereits standardmäßig aktiviert .
Günter Zöchbauer
2
Das war großartig, danke. Ich fand das auch nützlich, als ich versuchte, alles zusammenzusetzen: stackoverflow.com/questions/34391790/…
Jeff
Vielleicht eine dumme Frage hier, aber was ist RC.1, RC.2 hier? Ich benutze Angular 2.1.2, welcher RC ist das?
Jian Chen
1
@AlexanderMills warum erschrecken dich alte Türme? Alte Antworten sind kampferprobt und daher sehr vertrauenswürdig; p
Günter Zöchbauer
116

Für Personen, die dies finden, wenn sie versuchen, Tests auszuführen, weil über npm testoderng test mit Karma oder was auch immer. Ihr .spec-Modul benötigt einen speziellen Router-Testimport, um erstellt werden zu können.

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

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

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

Rayepps
quelle
2
Das ist ein toller Fang! Mein Projekt hatte kein Problem mit dem normalen Betrieb, es war in der specDatei, dass ich dies hinzufügen musste. Danke @raykrow!
kbpontius
1
Bestätigt, auch in Winkel 4 zu arbeiten. Danke dafür!
JCisar
Dies muss die akzeptierte Antwort sein, die akzeptierte Antwort ist falsch, denn beim Importieren RouterModulemüssen Sie anrufen forRoot, um das Modul zu erfüllen, und dann sollten Sie die BASE_HREFund ...
Milad
1
Haben Sie eine Idee, ob dies für Angular 5+ anders ist? Ich erhalte den ähnlichen Fehler Can't bind to 'active' since it isn't a known property of 'a'.in mehreren meiner Komponententests und habe importiert RouterTestingModule.
Stuart Updegrave
25

Vorsicht beim Codieren mit Visual Studio (2013)

Ich habe 4 bis 5 Stunden damit verbracht, diesen Fehler zu beheben. Ich habe alle Lösungen, die ich auf StackOverflow gefunden habe, per Brief ausprobiert und trotzdem den folgenden Fehler erhalten:Can't bind to 'routerlink' since it isn't a known native property

Beachten Sie, dass Visual Studio beim Kopieren / Einfügen von Code die unangenehme Angewohnheit hat, Text automatisch zu formatieren. Ich habe immer eine kleine sofortige Anpassung von VS13 erhalten (Kamelkoffer verschwindet).

Dies:

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

Wird:

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

Es ist ein kleiner Unterschied, aber genug, um den Fehler auszulösen. Das Hässlichste ist, dass dieser kleine Unterschied jedes Mal, wenn ich kopierte und einfügte, meine Aufmerksamkeit vermeidete. Durch Zufall habe ich diesen kleinen Unterschied gesehen und gelöst.

Adrian Moisa
quelle
4
Vielen Dank, Sie hätten den Unterschied zwischen "routerlink" und "routerLink" erwähnen können. Angular 2 erwartet, dass "routerLink" vorhanden ist, findet aber "routerlink"
Narendran Solai Sridharan
Vielen Dank, aus irgendeinem Grund, ein Tutorial verwendet "Router-Link" mit Bindestrich dazwischen. Aber routerLink ist die richtige Version.
Windmaomao
Das gleiche passiert mit Webpack und HTML-Minifier, aber nur in der Produktion. add caseSensitive: Entspricht den HTML-Loader-Optionen. Siehe: github.com/SamanthaAdrichem/webpack-3.9.1-splitted-config-an‌ gular für eine funktionierende Winkel 5 + Webpack 3.9-Konfiguration
Samantha Adrichem
12

Für> = V5

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

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

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

Komponente:

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

Für <V5

Kann auch RouterLinkals directivesdh verwendet werden. directives: [RouterLink]. das hat bei mir funktioniert

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},
])
Shaishab Roy
quelle
Ich glaube nicht, dass dies mehr zutrifft (Winkel 5) usw.
Alexander Mills
10

Wenn Sie einen Fehler wie erhalten Can't bind to 'xxx' since it isn't a known native property, besteht die wahrscheinlichste Ursache darin, dass Sie vergessen, eine Komponente oder eine Direktive (oder eine Konstante, die die Komponente oder die Direktive enthält) im directivesMetadatenarray anzugeben . Dies ist hier der Fall.

Da Sie nicht angegeben haben RouterLinkoder die Konstante ROUTER_DIRECTIVES- die Folgendes enthält :

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

- im directivesArray, dann, wenn Angular analysiert

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

es weiß nicht , über den Router Direktive (benutzt Attribut Selektor routerLink). Da Angular weiß, was das aElement ist, wird davon ausgegangen, dass [routerLink]="..."es sich um eine Eigenschaftsbindung für das aElement handelt. Dann stellt es jedoch fest, dass routerLinkes sich nicht um eine native Eigenschaft von aElementen handelt, und löst daher die Ausnahme für die unbekannte Eigenschaft aus.


Ich habe die Mehrdeutigkeit der Syntax nie wirklich gemocht . Dh überlegen

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

Wenn wir uns nur den HTML-Code ansehen, können wir nicht sagen, ob dies der Fall whatIsThisist

  • ein einheimisches Eigentum von something
  • Attributauswahl einer Direktive
  • eine Eingabeeigenschaft von something

Wir müssen wissen, welche directives: [...]in den Metadaten der Komponente / Direktive angegeben sind, um den HTML-Code mental zu interpretieren. Und wenn wir vergessen, etwas in das directivesArray aufzunehmen, macht es diese Mehrdeutigkeit meiner Meinung nach etwas schwieriger, Fehler zu beheben.

Mark Rajcok
quelle
7

Sie haben in Ihrem Modul

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

Sie müssen das Modul RouteModule exportieren

Beispiel:

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

um auf die Funktionen für alle zugreifen zu können, die dieses Modul importieren.

alehn96
quelle
5

Ich habe alle oben genannten Methoden ausprobiert. Aber keine Methode funktioniert für mich. Schließlich habe ich eine Lösung für das oben genannte Problem und sie funktioniert für mich.

Ich habe diese Methode ausprobiert:

In HTML:

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

In der TS-Datei:

aboutPageLoad() {
    this.router.navigate(['/about']);
}
Sunil Kumar KK
quelle
4

In meinem Fall habe ich das RouterModule im App-Modul importiert, aber nicht in mein Funktionsmodul importiert. Nach dem Import des Routermoduls in mein EventModule verschwindet der Fehler.

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 {

 }
Code-EZ
quelle
3

Wenn dieser Fehler beim Testen des Geräts auftritt, schreiben Sie dies bitte.

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

Ich schätze die Antwort von @ raykrow sehr, wenn man dieses Problem nur in einer Testdatei hat! Dort bin ich darauf gestoßen.

Da es oft hilfreich ist, eine andere Möglichkeit zu haben, etwas als Backup zu erstellen, wollte ich diese Technik erwähnen, die auch funktioniert (anstatt zu importieren RouterTestingModule):

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

(Normalerweise wird routerLinkein <a>Element verwendet, der Selektor wird jedoch für andere Komponenten entsprechend angepasst.)

Der zweite Grund, warum ich diese alternative Lösung erwähnen wollte, ist, dass ich, obwohl sie mir in einer Reihe von Spezifikationsdateien gute Dienste geleistet hat, in einem Fall auf ein Problem damit gestoßen bin:

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

Ich konnte nicht ButtonComponentgenau herausfinden, wie dieser Mock und ich denselben Selektor verwendeten. Die Suche nach einem alternativen Ansatz führte mich hier zu @ raykrows Lösung.

Michael Sorens
quelle
0

Wenn Sie gemeinsam genutzte Module verwenden, fügen Sie RouterModule einfach einem Modul hinzu, in dem Ihre Komponente deklariert ist, und vergessen Sie nicht, das Modul hinzuzufügen <router-outlet></router-outlet>

Von hier aus referenziert RouterLink funktioniert nicht

Yevheniy Potupa
quelle
-4

Meine Lösung ist einfach. Ich verwende [href] anstelle von [routerLink]. Ich habe alle Lösungen für [routerLink] ausprobiert. Keiner von ihnen funktioniert in meinem Fall.

Hier ist meine Lösung:

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

Schreiben Sie dann die getPlanUrlFunktion in die TS-Datei.

G Chen
quelle