ข้อยกเว้น Angular2: ไม่สามารถผูกกับ 'routerLink' ได้เนื่องจากไม่ใช่คุณสมบัติดั้งเดิมที่รู้จัก


277

เห็นได้ชัดว่าเบต้าของ Angular2 นั้นใหม่กว่าใหม่ดังนั้นจึงไม่มีข้อมูลมากนัก แต่ฉันพยายามทำในสิ่งที่ฉันคิดว่าเป็นเส้นทางขั้นพื้นฐานพอสมควร

การแฮ็กข้อมูลด้วยโค้ดเริ่มต้นอย่างรวดเร็วและตัวอย่างอื่น ๆ จากเว็บไซต์https://angular.ioส่งผลให้โครงสร้างไฟล์ต่อไปนี้:

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

ด้วยไฟล์ที่มีประชากรดังนี้:

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

เส้นทาง-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 { }

การพยายามเรียกใช้รหัสนี้ก่อให้เกิดข้อผิดพลาด:

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

ฉันพบปัญหาที่เกี่ยวข้องอย่างคลุมเครือที่นี่; สั่งเราเตอร์ลิงค์เสียหลังจากการอัพเกรด angular2.0.0-beta.0 อย่างไรก็ตาม "ตัวอย่างการทำงาน" ในหนึ่งในคำตอบนั้นขึ้นอยู่กับโค้ด pre-beta ซึ่งอาจยังใช้งานได้ดี แต่ฉันอยากจะรู้ว่าทำไมรหัสที่ฉันสร้างขึ้นไม่ทำงาน

พอยน์เตอร์ใด ๆ จะได้รับสุดซึ้ง!


4
คำถามอื่นมีความแตกต่าง: directives: [ROUTER_DIRECTIVES].
Eric Martinez

1
ฉันได้รับข้อผิดพลาดเดียวกันแม้กับ ROUTER_DIRECTIVE @Component({selector: "app"}) @View({templateUrl: "app.html", directives: [ROUTER_DIRECTIVES, RouterLink]})
ฟิล

8
ด้วยการเพิ่มdirectives: [ROUTER_DIRECTIVES]และเปลี่ยนจาก [router-link] เป็น [routerLink] ฉันไม่ได้รับข้อผิดพลาดอีกต่อไป
ฟิล

คำตอบ:


392

> = RC.5

นำเข้า RouterModule ดูเพิ่มเติมที่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

รหัสของคุณหายไป

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

คุณไม่สามารถใช้คำสั่งเช่น routerLinkหรือrouter-outletไม่แจ้งให้ส่วนประกอบของคุณทราบ

ในขณะที่ชื่อคำสั่งถูกเปลี่ยนเป็น case-sensitive ใน Angular2 องค์ประกอบยังคงใช้ -ในชื่อ<router-outlet>ที่จะเข้ากันได้กับ spec ขององค์ประกอบของเว็บที่ต้องการ-ชื่อในองค์ประกอบที่กำหนดเอง

ลงทะเบียนทั่วโลก

หากต้องการให้ROUTER_DIRECTIVESบริการทั่วโลกเพิ่มผู้ให้บริการนี้ไปที่bootstrap(...):

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

ดังนั้นจึงไม่จำเป็นต้องเพิ่มROUTER_DIRECTIVESองค์ประกอบแต่ละตัวอีกต่อไป


1
ใช่คุณสามารถกำหนดหลาย ๆ คำสั่งได้ในขณะที่บูตแอปของคุณเช่นนี้:provide(PLATFORM_DIRECTIVES, {useValue: [ROUTER_DIRECTIVES, FORM_DIRECTIVES, ETC...], multi: true})
Pardeep Jain

1
ถูกต้อง แต่FORM_DIRECTIVESรวมอยู่ในPLATFORM_DIRECTIVESค่าเริ่มต้นแล้ว
GünterZöchbauer

2
ขอบคุณมาก ฉันยังพบว่ามีประโยชน์เมื่อพยายามรวบรวมทั้งหมด: stackoverflow.com/questions/34391790/…
Jeff

อาจเป็นคำถามที่โง่ที่นี่ แต่ RC.1, RC.2 คืออะไรที่นี่? ฉันใช้แองกูลาร์ 2.1.2 แล้วมันคือ RC อะไร?
เจียนเฉิน

1
@AlexanderMills ทำไมคนที่แก่และทำให้คุณกลัว? คำตอบเก่าคือการทดสอบการต่อสู้และน่าเชื่อถือมาก p
GünterZöchbauer

116

สำหรับผู้ที่พบสิ่งนี้เมื่อพยายามเรียกใช้การทดสอบเพราะผ่านnpm testหรือng testใช้กรรมหรืออย่างอื่น โมดูล. spec ของคุณต้องการการนำเข้าการทดสอบเราเตอร์พิเศษเพื่อให้สามารถสร้างได้

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

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

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


2
นี่เป็นสิ่งที่ยอดเยี่ยมมาก! โครงการของฉันไม่มีปัญหากับการทำงานปกติมันอยู่ในspecไฟล์ที่ฉันต้องเพิ่ม ขอบคุณ @raykrow!
kbpontius

1
ยืนยันการทำงานในมุม 4 เช่นกัน ขอบคุณสำหรับสิ่งนี้!
JCisar

นี่จะต้องเป็นคำตอบที่ได้รับการยอมรับคำตอบที่ยอมรับนั้นผิดเพราะเมื่อนำเข้า RouterModuleคุณต้องโทรหาforRootโมดูลเพื่อตอบสนองแล้วคุณควรจะจัดหาBASE_HREFและ ...
Milad

1
คุณมีความคิดใด ๆ ไหมถ้าสิ่งนี้ต่างไปสำหรับ Angular 5+? ฉันได้รับข้อผิดพลาดที่คล้ายกันCan't bind to 'active' since it isn't a known property of 'a'.ในการทดสอบหน่วยต่างๆของฉันและได้นำเข้าRouterTestingModuleแล้ว
Stuart Updegrave

25

คำเตือนเมื่อเข้ารหัสด้วย Visual Studio (2013)

ฉันเสียเวลา 4 ถึง 5 ชั่วโมงในการพยายามแก้ไขข้อผิดพลาดนี้ ฉันลองวิธีแก้ไขปัญหาทั้งหมดที่พบใน StackOverflow ด้วยตัวอักษรและฉันยังพบข้อผิดพลาดนี้:Can't bind to 'routerlink' since it isn't a known native property

โปรดทราบว่า Visual Studio มีนิสัยที่น่ารังเกียจในการจัดรูปแบบข้อความโดยอัตโนมัติเมื่อคุณคัดลอก / วางรหัส ฉันได้รับการปรับทันทีเล็กน้อยจาก VS13 (กรณีอูฐหายไป)

นี้:

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

กลายเป็น:

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

มันต่างกันเล็กน้อย แต่ก็เพียงพอที่จะทำให้เกิดข้อผิดพลาดได้ ส่วนที่น่าเกลียดที่สุดก็คือความแตกต่างเล็ก ๆ นี้เพียง แต่หลีกเลี่ยงความสนใจของฉันทุกครั้งที่ฉันคัดลอกและวาง โดยโอกาสที่แท้จริงฉันเห็นความแตกต่างเล็กน้อยนี้และแก้ไขมัน


4
ขอบคุณคุณสามารถพูดถึงความแตกต่างในกรณีระหว่าง "เราเตอร์ลิงค์" กับ "เราเตอร์ลิงค์" Angular 2 คาดว่าจะมี "routerLink" ปรากฏ แต่พบ "routerlink"
Narendran Solai Sridharan

ขอบคุณด้วยเหตุผลบางอย่างบทช่วยสอนบางอย่างใช้ "เราเตอร์ลิงค์" พร้อมกับขีดกลาง แต่ routerLink เป็นรุ่นที่ถูกต้อง
windmaomao

สิ่งเดียวกันนี้เกิดขึ้นกับ webpack และ html-minifier แต่มีเฉพาะในการผลิตเท่านั้น เพิ่ม caseSensitive: จริงกับตัวเลือก html-loader ดู: github.com/SamanthaAdrichem/webpack-3.9.1-splitted-config-an‌ gular สำหรับการทำงานเชิงมุม 5 + webpack 3.9 config
Samantha Adrichem

12

สำหรับ> = V5

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

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

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

ส่วนประกอบ:

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

สำหรับ <V5

นอกจากนี้ยังสามารถใช้RouterLinkเป็นdirectivesเช่น directives: [RouterLink]. ที่ทำงานให้ฉัน

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

ฉันไม่คิดว่ามันจะใช้งานได้อีกต่อไป (Angular 5) ฯลฯ
Alexander Mills

10

โดยทั่วไปเมื่อใดก็ตามที่คุณได้รับข้อผิดพลาดCan't bind to 'xxx' since it isn't a known native propertyสาเหตุที่เป็นไปได้มากที่สุดคือการลืมระบุส่วนประกอบหรือคำสั่ง (หรือค่าคงที่ที่มีส่วนประกอบหรือคำสั่ง) ในdirectivesอาร์เรย์เมทาดาทา นี่เป็นกรณีที่นี่

เนื่องจากคุณไม่ได้ระบุRouterLinkหรือค่าคงที่ROUTER_DIRECTIVES- ซึ่งมีดังต่อไปนี้ :

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

- ในdirectivesอาเรย์แล้วเมื่อแองกูลาร์วิเคราะห์คำ

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

มันไม่รู้เกี่ยวกับ คำสั่ง RouterLink (ซึ่งใช้ตัวเลือกแอททริบิวต์routerLink ) เนื่องจาก Angular รู้ว่าaองค์ประกอบคืออะไรจึงสันนิษฐานว่า[routerLink]="..."เป็นคุณสมบัติที่มีผลผูกพันกับaองค์ประกอบ แต่มันก็ค้นพบว่าrouterLinkไม่ใช่คุณสมบัติดั้งเดิมของaองค์ประกอบดังนั้นจึงมีข้อยกเว้นเกี่ยวกับคุณสมบัติที่ไม่รู้จัก


ฉันไม่เคยชอบความกำกวมของไวยากรณ์จริงๆ คือพิจารณา

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

เพียงแค่ดูที่ HTML เราไม่สามารถบอกได้ว่าwhatIsThisเป็น

  • ทรัพย์สินพื้นเมืองของ something
  • ตัวเลือกคุณลักษณะของคำสั่ง
  • คุณสมบัติอินพุตของ something

เราต้องรู้ว่า directives: [...]มีอะไรระบุไว้ในเมตาดาต้าของ / คำสั่งขององค์ประกอบเพื่อตีความ HTML ทางจิตใจ และเมื่อเราลืมใส่บางอย่างในdirectivesอาเรย์ฉันรู้สึกว่าความกำกวมนี้ทำให้การดีบักยากขึ้นเล็กน้อย


7

คุณมีในโมดูลของคุณ

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

คุณต้องส่งออกโมดูล RouteModule

ตัวอย่าง:

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

เพื่อให้สามารถเข้าถึงฟังก์ชันการทำงานสำหรับทุกคนที่นำเข้าโมดูลนี้


5

ฉันได้ลองวิธีการทั้งหมดซึ่งกล่าวถึงข้างต้น แต่ไม่มีวิธีการใดที่เหมาะกับฉันในที่สุดฉันก็มีทางออกสำหรับปัญหาด้านบนและมันก็ใช้ได้กับฉันด้วย

ฉันลองวิธีนี้:

ใน Html:

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

ในไฟล์ TS:

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

4

ในกรณีของฉันฉันได้นำเข้าRouterModuleในโมดูล App แต่ไม่ได้นำเข้าในโมดูลคุณสมบัติของฉัน หลังจากอิมพอร์ตโมดูลเราเตอร์ใน EventModule ของฉันข้อผิดพลาดจะหายไป

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

หากได้รับข้อผิดพลาดนี้ในขณะทดสอบหน่วยโปรดเขียนสิ่งนี้

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

0

ฉันขอบคุณคำตอบของ @ raykrow จริงๆเมื่อมีปัญหานี้ในไฟล์ทดสอบเท่านั้น! นั่นคือที่ฉันพบมัน

บ่อยครั้งที่มีประโยชน์ที่จะมีวิธีอื่นในการสำรองข้อมูลฉันต้องการพูดถึงเทคนิคนี้ที่ใช้งานได้ (แทนที่จะนำเข้าRouterTestingModule):

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

(โดยทั่วไปแล้วจะใช้routerLinkกับ<a>องค์ประกอบ แต่ปรับตัวเลือกตามส่วนประกอบอื่น ๆ )

เหตุผลที่สองที่ฉันต้องการพูดถึงวิธีการแก้ปัญหาทางเลือกนี้คือแม้ว่ามันจะให้บริการฉันได้ดีในไฟล์ spec จำนวนหนึ่ง แต่ฉันพบปัญหากับมันในกรณีเดียว:

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

ฉันไม่สามารถคิดได้ว่าเยาะเย้ยนี้และฉันButtonComponentใช้ตัวเลือกเดียวกันดังนั้นการค้นหาวิธีอื่นทำให้ฉันมาที่โซลูชันของ @ raykrow



-4

ทางออกของฉันง่าย ฉันใช้ [href] แทน [routerLink] ฉันได้ลองวิธีแก้ปัญหาทั้งหมดสำหรับ [routerLink] ไม่มีพวกเขาทำงานในกรณีของฉัน

นี่คือทางออกของฉัน:

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

จากนั้นเขียนgetPlanUrlฟังก์ชันในไฟล์ TS

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.