Angular2 Ngoại lệ: Không thể liên kết với 'routerLink' vì đây không phải là tài sản bản địa đã biết


277

Rõ ràng bản beta cho Angular2 mới hơn bản mới, vì vậy không có nhiều thông tin ngoài đó, nhưng tôi đang cố gắng thực hiện những gì tôi nghĩ là một số định tuyến khá cơ bản.

Việc hack về mã bắt đầu nhanh và các đoạn mã khác từ trang web https://angular.io đã dẫn đến cấu trúc tệp sau:

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

Với các tệp được điền như sau:

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

định tuyến-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 { }

Cố gắng chạy mã này tạo ra lỗi:

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

Tôi tìm thấy một vấn đề mơ hồ liên quan ở đây; các chỉ thị liên kết bộ định tuyến bị hỏng sau khi nâng cấp lên angular2.0.0-beta.0 . Tuy nhiên, "ví dụ hoạt động" trong một trong các câu trả lời dựa trên mã pre-beta - có thể vẫn hoạt động, nhưng tôi muốn biết lý do tại sao mã tôi đã tạo không hoạt động.

Bất kỳ con trỏ sẽ được biết ơn nhận được!


4
Các câu hỏi khác có một cái gì đó khác nhau : directives: [ROUTER_DIRECTIVES].
Eric Martinez

1
Tôi nhận được cùng một lỗi ngay cả với ROUTER_DIRECTIVES. @Component({selector: "app"}) @View({templateUrl: "app.html", directives: [ROUTER_DIRECTIVES, RouterLink]})
phil

8
Với việc bổ sung directives: [ROUTER_DIRECTIVES]và thay đổi từ [liên kết bộ định tuyến] sang [bộ định tuyến] tôi không còn gặp phải lỗi này nữa.
phil

Câu trả lời:


392

> = RC.5

nhập vào RouterModule Xem thêm 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)];

chính

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

bootstrap(AppComponent, [APP_ROUTER_PROVIDERS]);

<= RC.1

Mã của bạn bị thiếu

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

Bạn không thể sử dụng các chỉ thị như routerLinkhoặc router-outletkhông làm cho chúng được biết đến với thành phần của bạn.

Mặc dù các tên chỉ thị đã được thay đổi thành phân biệt chữ hoa chữ thường trong Angular2, các phần tử vẫn sử dụng -trong tên đó <router-outlet>để tương thích với thông số thành phần web yêu cầu một -tên của các phần tử tùy chỉnh.

đăng ký toàn cầu

Để ROUTER_DIRECTIVEScung cấp toàn cầu, hãy thêm nhà cung cấp này vào bootstrap(...):

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

sau đó không còn cần thiết phải thêm ROUTER_DIRECTIVESvào từng thành phần.


1
vâng, bạn cũng có thể chỉ định nhiều chỉ thị tại thời điểm khởi động ứng dụng của mình như thế này: -provide(PLATFORM_DIRECTIVES, {useValue: [ROUTER_DIRECTIVES, FORM_DIRECTIVES, ETC...], multi: true})
Pardeep Jain

1
Điều đó đúng, nhưng FORM_DIRECTIVESđược bao gồm trong PLATFORM_DIRECTIVESmặc định.
Günter Zöchbauer

2
Điều này thật tuyệt, cảm ơn. Tôi cũng thấy điều này hữu ích khi cố gắng kết hợp tất cả lại với nhau: stackoverflow.com/questions
Jeff

Có thể một câu hỏi ngu ngốc ở đây, nhưng RC.1, RC.2 ở đây là gì? Tôi đang sử dụng 2.1.2, đó là RC nào?
Jian Chen

1
@AlexanderMills tại sao các andwers cũ làm bạn sợ? Câu trả lời cũ được thử nghiệm chiến đấu và do đó rất đáng tin cậy; p
Günter Zöchbauer

116

Đối với những người tìm thấy điều này khi cố gắng chạy thử nghiệm vì thông qua npm testhoặc ng testsử dụng Karma hoặc bất cứ điều gì khác. Mô-đun .spec của bạn cần nhập kiểm tra bộ định tuyến đặc biệt để có thể xây dựng.

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

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

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


2
Đây là một bắt tuyệt vời! Dự án của tôi không có vấn đề gì với hoạt động bình thường, đó là trong spectập tin mà tôi phải thêm nó. Cảm ơn @raykrow!
kbpontius

1
Khẳng định làm việc ở góc 4 là tốt. Cảm ơn vì điều đó!
JCisar

Đây phải là câu trả lời được chấp nhận, câu trả lời được chấp nhận là sai, vì khi nhập RouterModule, sau đó bạn cần gọi forRootđể đáp ứng mô-đun và sau đó bạn nên cung cấp BASE_HREFvà ...
Milad

1
Bạn có biết nếu điều này khác với Angular 5+ không? Tôi nhận được lỗi tương tự Can't bind to 'active' since it isn't a known property of 'a'.trong một số bài kiểm tra đơn vị của mình và đã nhập RouterTestingModule.
Stuart Updegrave

25

Lời cảnh báo khi mã hóa với Visual Studio (2013)

Tôi đã lãng phí 4 đến 5 giờ để cố gắng sửa lỗi này. Tôi đã thử tất cả các giải pháp mà tôi tìm thấy trên StackOverflow bằng thư và tôi vẫn gặp lỗi này:Can't bind to 'routerlink' since it isn't a known native property

Xin lưu ý, Visual Studio có thói quen khó chịu khi tự động định dạng văn bản khi bạn sao chép / dán mã. Tôi luôn có một sự điều chỉnh tức thời nhỏ từ VS13 (trường hợp lạc đà biến mất).

Điều này:

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

Trở thành:

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

Đó là một sự khác biệt nhỏ, nhưng đủ để gây ra lỗi. Phần xấu nhất là sự khác biệt nhỏ này chỉ tránh sự chú ý của tôi mỗi khi tôi sao chép và dán. Cơ hội tuyệt đối, tôi đã thấy sự khác biệt nhỏ này và giải quyết nó.


4
Cảm ơn bạn, bạn có thể đã đề cập đến sự khác biệt trong trường hợp giữa "routerlink" so với "routerLink". Angular 2 dự kiến ​​sẽ có "routerLink" nhưng tìm thấy "routerlink"
Narendran Solai Sridharan

Cảm ơn bạn, vì một số lý do, một số hướng dẫn đã sử dụng "bộ định tuyến liên kết" với dấu gạch ngang ở giữa. Nhưng routerLink là phiên bản chính xác.
Windmaomao

Điều tương tự cũng xảy ra với webpack và html-minifier, nhưng chỉ trong sản xuất. thêm caseSensitive: đúng với các tùy chọn trình tải html, xem: github.com/SamanthaAdrichem/webpack-3.9.1-splited-config-an‌ gular cho một cấu hình 5 + webpack 3.9 hoạt động
Samantha Adrichem

12

Cho> = V5

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

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

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

thành phần:

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

Dành cho <V5

Cũng có thể sử dụng RouterLinknhư một directivesnghĩa. directives: [RouterLink]. điều đó làm việc cho tôi

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

Tôi không nghĩ điều này được áp dụng nữa (Angular 5), v.v.
Alexander Mills

10

Nói chung, bất cứ khi nào bạn gặp lỗi như thế Can't bind to 'xxx' since it isn't a known native property, nguyên nhân rất có thể là quên chỉ định một thành phần hoặc lệnh (hoặc hằng số chứa thành phần hoặc lệnh) trong directivesmảng siêu dữ liệu. Đó là trường hợp ở đây.

Vì bạn không chỉ định RouterLinkhoặc hằng số ROUTER_DIRECTIVES- có chứa các mục sau :

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

- trong directivesmảng, sau đó khi phân tích góc

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

nó không biết về chỉ thị RouterLink (sử dụng bộ chọn thuộc tínhrouterLink ). Vì Angular không biết aphần tử là gì, nên nó giả sử đó [routerLink]="..."là một thuộc tính ràng buộc cho aphần tử. Nhưng sau đó nó phát hiện ra rằng đó routerLinkkhông phải là một tài sản riêng của acác yếu tố, do đó nó ném ngoại lệ về thuộc tính không xác định.


Tôi chưa bao giờ thực sự thích sự mơ hồ của cú pháp . Tức là xem xét

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

Chỉ cần nhìn vào HTML chúng ta không thể biết nếu whatIsThis

  • một tài sản bản địa của something
  • bộ chọn thuộc tính của chỉ thị
  • một thuộc tính đầu vào của something

Chúng ta phải biết directives: [...]được chỉ định trong siêu dữ liệu của thành phần / chỉ thị để diễn giải một cách tinh thần HTML. Và khi chúng ta quên đặt một cái gì đó vào directivesmảng, tôi cảm thấy sự mơ hồ này làm cho việc gỡ lỗi khó hơn một chút.


7

Bạn có trong mô-đun của bạn

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

bạn phải xuất mô-đun RouteModule

thí dụ:

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

để có thể truy cập các chức năng cho tất cả những ai nhập mô-đun này.


5

Tôi đã thử tất cả các phương pháp, được đề cập ở trên. Nhưng không có phương pháp nào phù hợp với tôi. Cuối cùng tôi đã có giải pháp cho vấn đề trên và nó đang hoạt động với tôi.

Tôi đã thử phương pháp này:

Trong Html:

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

Trong tệp TS:

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

4

Trong trường hợp của tôi, tôi đã nhập RouterModule trong mô-đun Ứng dụng nhưng không được nhập trong mô-đun tính năng của mình. Sau khi nhập mô-đun bộ định tuyến trong EventModule của tôi, lỗi sẽ biến mấ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 {

 }

3

Nếu nhận được lỗi này trong khi kiểm tra đơn vị xin vui lòng viết này.

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

0

Tôi thực sự đánh giá cao câu trả lời của @ raykrow khi một người chỉ gặp vấn đề này trong một tệp thử nghiệm! Đó là nơi tôi bắt gặp nó.

Vì thường hữu ích khi có một cách khác để làm một cái gì đó như một bản sao lưu, tôi muốn đề cập đến kỹ thuật này cũng hoạt động (thay vì nhập RouterTestingModule):

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

(Thông thường, người ta sẽ sử dụng routerLinktrên một <a>phần tử nhưng điều chỉnh bộ chọn phù hợp cho các thành phần khác.)

Lý do thứ hai tôi muốn đề cập đến giải pháp thay thế này là, mặc dù nó phục vụ tốt cho tôi trong một số tệp spec, tôi đã gặp phải một vấn đề với nó trong một trường hợp:

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

Tôi hoàn toàn không thể hiểu được cách giả này và tôi ButtonComponentđang sử dụng cùng một bộ chọn, vì vậy việc tìm kiếm một phương pháp thay thế đã đưa tôi đến đây với giải pháp của @ raykrow.


0

Nếu bạn sử dụng các mô-đun được chia sẻ, chỉ cần thêm RouterModule vào Mô-đun nơi thành phần của bạn được khai báo và đừng quên thêm <router-outlet></router-outlet>

Tham chiếu từ đây RouterLink không hoạt động


-4

Giải pháp của tôi rất đơn giản. Tôi đang sử dụng [href] thay vì [routerLink]. Tôi đã thử tất cả các giải pháp cho [routerLink]. Không ai trong số họ làm việc trong trường hợp của tôi.

Đây là giải pháp của tôi:

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

Sau đó viết getPlanUrlhàm trong tệp TS.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.