Pengecualian Angular2: Tidak dapat mengikat ke 'routerLink' karena itu bukan properti asli yang dikenal

277

Jelas beta untuk Angular2 lebih baru daripada yang baru, jadi tidak ada banyak informasi di luar sana, tapi saya mencoba melakukan apa yang saya pikir merupakan beberapa rute yang cukup mendasar.

Meretas dengan kode mulai cepat dan cuplikan lainnya dari situs web https://angular.io telah menghasilkan struktur file berikut:

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

Dengan file yang sedang diisi sebagai berikut:

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

Mencoba menjalankan kode ini menghasilkan kesalahan:

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

Saya menemukan masalah yang samar-samar terkait di sini; arahan router-link rusak setelah memutakhirkan ke angular2.0.0-beta.0 . Namun, "contoh kerja" di salah satu jawaban didasarkan pada kode pra-beta - yang mungkin masih berfungsi, tetapi saya ingin tahu mengapa kode yang saya buat tidak berfungsi.

Pointer apa pun akan diterima dengan penuh syukur!

Lester Burnham
sumber
4
Pertanyaan lain memiliki sesuatu yang berbeda: directives: [ROUTER_DIRECTIVES].
Eric Martinez
1
Saya mendapatkan kesalahan yang sama bahkan dengan ROUTER_DIRECTIVES. @Component({selector: "app"}) @View({templateUrl: "app.html", directives: [ROUTER_DIRECTIVES, RouterLink]})
phil
8
Dengan penambahan directives: [ROUTER_DIRECTIVES]dan perubahan dari [router-link] ke [routerLink] saya tidak lagi mendapatkan kesalahan.
phil

Jawaban:

392

> = RC.5

impor RouterModule Lihat juga 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

Kode Anda tidak ada

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

Anda tidak dapat menggunakan arahan seperti routerLinkatau router-outlettanpa membuatnya diketahui oleh komponen Anda.

Sementara nama direktif diubah menjadi case-sensitive di Angular2, elemen masih menggunakan -dalam nama ingin <router-outlet>kompatibel dengan spesifikasi komponen web yang memerlukan -nama elemen kustom.

daftar secara global

Untuk membuat ROUTER_DIRECTIVEStersedia secara global, tambahkan penyedia ini ke bootstrap(...):

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

maka tidak perlu lagi menambahkan ROUTER_DIRECTIVESke setiap komponen.

Günter Zöchbauer
sumber
1
ya Anda dapat menetapkan banyak arahan juga pada saat bootstrap aplikasi Anda seperti ini: -provide(PLATFORM_DIRECTIVES, {useValue: [ROUTER_DIRECTIVES, FORM_DIRECTIVES, ETC...], multi: true})
Pardeep Jain
1
Itu benar, tetapi FORM_DIRECTIVESsudah termasuk dalam PLATFORM_DIRECTIVESstandar.
Günter Zöchbauer
2
Ini bagus, terima kasih. Saya juga menemukan ini berguna ketika mencoba untuk menyatukan semuanya: stackoverflow.com/questions/34391790/…
Jeff
Mungkin pertanyaan bodoh di sini, tapi apa itu RC.1, RC.2 di sini? Saya menggunakan sudut 2.1.2, RC mana yang benar?
Jian Chen
1
@AlexanderMills mengapa tua dan ketakutan membuat Anda? Jawaban lama sudah teruji dalam pertempuran dan karenanya sangat dapat dipercaya; p
Günter Zöchbauer
116

Untuk orang yang menemukan ini ketika mencoba menjalankan tes karena melalui npm testatau ng testmenggunakan Karma atau apa pun. Modul .spec Anda memerlukan impor pengujian router khusus untuk dapat dibuat.

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

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

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

rayepps
sumber
2
Ini tangkapan yang bagus! Proyek saya tidak memiliki masalah dengan operasi normal, itu dalam specfile yang saya harus tambahkan ini. Terima kasih @raykrow!
kbpontius
1
Dikonfirmasi untuk bekerja dalam sudut 4 juga. Terima kasih untuk ini!
JCisar
Ini harus menjadi jawaban yang diterima, jawaban yang diterima salah, karena ketika mengimpor RouterModule, maka Anda perlu menelepon forRootuntuk memenuhi modul dan kemudian Anda harus memberikan BASE_HREFdan ...
Milad
1
Apakah Anda tahu jika ini berbeda untuk Angular 5+? Saya mendapatkan kesalahan serupa Can't bind to 'active' since it isn't a known property of 'a'.di beberapa pengujian unit saya, dan telah mengimpor RouterTestingModule.
Stuart Updegrave
25

Hati-hati saat coding dengan Visual Studio (2013)

Saya telah membuang waktu 4 hingga 5 jam untuk mencoba men-debug kesalahan ini. Saya mencoba semua solusi yang saya temukan di StackOverflow oleh surat itu dan saya masih mendapatkan kesalahan ini:Can't bind to 'routerlink' since it isn't a known native property

Ketahuilah, Visual Studio memiliki kebiasaan buruk pada teks autoformatting ketika Anda menyalin / menempelkan kode. Saya selalu mendapat penyesuaian instan kecil dari VS13 (case unta menghilang).

Ini:

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

Menjadi:

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

Ini perbedaan kecil, tetapi cukup untuk memicu kesalahan. Bagian terburuk adalah perbedaan kecil ini terus menghindari perhatian saya setiap kali saya menyalin dan menempel. Secara kebetulan, saya melihat perbedaan kecil ini dan menyelesaikannya.

Adrian Moisa
sumber
4
Terima kasih, Anda bisa menyebutkan perbedaan antara "routerlink" vs "routerLink". Angular 2 mengharapkan "routerLink" hadir tetapi menemukan "routerlink"
Narendran Solai Sridharan
Terima kasih, untuk beberapa alasan, beberapa tutorial menggunakan "router-link" dengan tanda hubung di antaranya. Tetapi routerLink adalah versi yang benar.
windmaomao
Hal yang sama terjadi dengan webpack dan html-minifier, tetapi hanya dalam produksi. tambahkan caseSensitive: sesuai dengan opsi html-loader, lihat: github.com/SamanthaAdrichem/webpack-3.9.1-splitted-config-an‌ gular untuk sudut kerja 5 + webpack 3.9 config
Samantha Adrichem
12

Untuk> = V5

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

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

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

komponen:

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

Untuk <V5

Juga bisa digunakan RouterLinksebagai contoh directives. directives: [RouterLink]. itu berhasil untuk saya

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
sumber
Saya tidak berpikir ini berlaku lagi (Sudut 5) dll.
Alexander Mills
10

Secara umum, setiap kali Anda mendapatkan kesalahan seperti Can't bind to 'xxx' since it isn't a known native property, penyebab yang paling mungkin adalah lupa untuk menentukan komponen atau arahan (atau konstanta yang berisi komponen atau arahan) dalam directivesarray metadata. Seperti halnya di sini.

Karena Anda tidak menentukan RouterLinkatau konstanta ROUTER_DIRECTIVES- yang berisi yang berikut ini :

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

- Dalam directivesarray, lalu ketika Angular mem-parsing

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

tidak tahu tentang direktif RouterLink (yang menggunakan pemilih atributrouterLink ). Karena Angular tahu apa aelemen itu, ia mengasumsikan bahwa itu [routerLink]="..."adalah properti yang mengikat untuk aelemen tersebut. Tetapi kemudian menemukan bahwa routerLinkitu bukan properti asli dari aelemen, maka ia melemparkan pengecualian tentang properti yang tidak diketahui.


Saya tidak pernah benar-benar menyukai ambiguitas sintaksis . Yaitu, pertimbangkan

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

Hanya dengan melihat HTML, kami tidak tahu apakah whatIsThisitu HTML

  • properti asli dari something
  • pemilih atribut direktif
  • properti input dari something

Kita harus tahu mana directives: [...]yang ditentukan dalam metadata komponen / direktif untuk menafsirkan secara mental HTML. Dan ketika kita lupa untuk memasukkan sesuatu ke dalam directivesarray, saya merasa ambiguitas ini membuatnya agak sulit untuk di-debug.

Mark Rajcok
sumber
7

Anda miliki di modul Anda

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

Anda harus mengekspor modul RouteModule

contoh:

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

untuk dapat mengakses fungsi untuk semua yang mengimpor modul ini.

alehn96
sumber
5

Saya telah mencoba semua metode, yang disebutkan di atas. Tetapi tidak ada satu metode yang berfungsi untuk saya. Akhirnya saya mendapat solusi untuk masalah di atas dan itu bekerja untuk saya.

Saya mencoba metode ini:

Dalam Html:

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

Dalam file TS:

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

Dalam kasus saya, saya telah mengimpor RouterModule dalam modul Aplikasi tetapi tidak diimpor dalam modul fitur saya. Setelah mengimpor modul router di EventModule saya kesalahan hilang.

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 {

 }
Kode-EZ
sumber
3

Jika mendapatkan kesalahan ini saat pengujian unit, harap tulis ini.

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

Saya sangat menghargai jawaban @ raykrow ketika seseorang memiliki masalah ini hanya dalam file uji! Di situlah saya menemukannya.

Karena sering membantu memiliki cara lain untuk melakukan sesuatu sebagai cadangan, saya ingin menyebutkan teknik ini yang juga berfungsi (alih-alih mengimpor RouterTestingModule):

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

(Biasanya, orang akan menggunakan routerLinkpada <a>elemen tetapi menyesuaikan pemilih yang sesuai untuk komponen lainnya.)

Alasan kedua saya ingin menyebutkan solusi alternatif ini adalah bahwa, meskipun itu membantu saya dengan baik dalam sejumlah file spesifikasi, saya mengalami masalah dengan itu dalam satu kasus:

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

Saya tidak tahu bagaimana tiruan ini dan saya ButtonComponentmenggunakan pemilih yang sama, jadi mencari pendekatan alternatif membawa saya ke sini untuk solusi @ raykrow.

Michael Sorens
sumber
0

Jika Anda menggunakan modul bersama, cukup tambahkan RouterModule ke Modul tempat komponen Anda dideklarasikan dan jangan lupa untuk menambahkan <router-outlet></router-outlet>

Dirujuk dari sini RouterLink tidak berfungsi

Yevheniy Potupa
sumber
-4

Solusi saya sederhana. Saya menggunakan [href] bukan [routerLink]. Saya telah mencoba semua solusi untuk [routerLink]. Tak satu pun dari mereka bekerja dalam kasus saya

Ini solusinya:

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

Kemudian tulis getPlanUrlfungsi di file TS.

G Chen
sumber