Angular2异常:无法绑定到'routerLink',因为它不是已知的本机属性

时间:2015-12-16 16:21:19

标签: angular

显然,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

我在这里发现了一个模糊的相关问题; router-link directives broken after upgrading to angular2.0.0-beta.0。但是,其中一个答案中的“工作示例”是基于预测试代码 - 这可能仍然有效,但我想知道为什么我创建的代码不起作用。

任何指针都会感激不尽!

12 个答案:

答案 0 :(得分:342)

<强>&GT; = RC.5

导入RouterModule 另请参阅https://angular.io/guide/router

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

<强>&GT; = 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]);

<强>&LT = RC.1

您的代码丢失

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

您不能使用routerLinkrouter-outlet等指令,而不会让您的组件知道它们。

虽然Angular2中的指令名称已更改为区分大小写,但元素仍然使用-等名称中的<router-outlet>与要求-的网络组件规范兼容在自定义元素的名称。

全球注册

要使ROUTER_DIRECTIVES全球可用,请将此提供商添加到bootstrap(...)

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

然后不再需要为每个组件添加ROUTER_DIRECTIVES

答案 1 :(得分:96)

对于在尝试运行测试时发现此问题的人,因为通过npm testng test使用Karma或其他任何内容。您的.spec模块需要一个特殊的路由器测试导入才能构建。

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

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

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

答案 2 :(得分:23)

使用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>

这是一个小差异,但足以触发错误。最丑陋的部分是,每次复制和粘贴时,这个小差异都会让我不再注意。通过纯粹的机会,我看到了这个小小的差异并解决了它。

答案 3 :(得分:9)

对于&gt; = 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>
        `
})

For&lt; 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},
])

答案 4 :(得分:8)

通常,每当出现Can't bind to 'xxx' since it isn't a known native property之类的错误时,最可能的原因是忘记在directives中忘记指定组件或指令(或包含组件或指令的常量)元数据数组。情况就是这样。

由于您未指定RouterLink或常量ROUTER_DIRECTIVES - contains the following

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

- 在directives数组中,然后当Angular解析

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

它不知道RouterLink directive(使用属性选择器routerLink)。由于Angular确实知道a元素是什么,因此它假定[routerLink]="..."a元素的属性绑定。但它随后发现routerLink不是a元素的本机属性,因此它抛出了有关未知属性的异常。

我从未真正喜欢ambiguity of the syntax。即,考虑

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

通过查看HTML,我们无法判断whatIsThis是否

  • something
  • 的原生属性
  • 指令的属性选择器
  • 输入属性something

我们必须知道在组件/指令的元数据中指定了哪个directives: [...]才能在心理上解释HTML。当我们忘记在directives数组中添加某些内容时,我觉得这种模糊性会让调试变得更加困难。

答案 5 :(得分:7)

你的模块中有

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

您必须导出模块RouteModule

示例:

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

能够访问导入此模块的所有人的功能。

答案 6 :(得分:4)

在我的情况下,我在App模块中导入了 RouterModule ,但未在我的功能模块中导入。在我的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 {

 }

答案 7 :(得分:2)

我已经尝试了上面提到的所有方法。但是没有一种方法适用于我。最终我得到了上述问题的解决方案,它对我有用。

我试过这个方法:

在Html中:

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

在TS文件中:

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

答案 8 :(得分:1)

如果在单元测试过程中出现此错误,请写下。

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

答案 9 :(得分:0)

我非常感谢@ raykrow的回答,只有在测试文件中出现此问题!这就是我遇到的地方。

由于通过另一种方式做一些事情作为备份通常很有帮助,我想提一下这种技术也有用(而不是导入Sub ImportAll() Dim blnHasFieldNames As Boolean, blnEXCEL As Boolean, blnReadOnly As Boolean Dim lngCount As Long Dim objExcel As Object, objWorkbook As Object Dim colWorksheets As Collection Dim strPathFile as String, strTable as String Dim strPassword As String ' Establish an EXCEL application object On Error Resume Next Set objExcel = GetObject(, "Excel.Application") If Err.Number <> 0 Then Set objExcel = CreateObject("Excel.Application") blnEXCEL = True End If Err.Clear On Error GoTo 0 ' Change this next line to True if the first row in EXCEL worksheet ' has field names blnHasFieldNames = False ' Replace C:\Filename.xls with the actual path and filename strPathFile = "C:\Filename.xls" ' Replace tablename with the real name of the table into which ' the data are to be imported strTable = "tablename" ' Replace passwordtext with the real password; ' if there is no password, replace it with vbNullString constant ' (e.g., strPassword = vbNullString) strPassword = "passwordtext" blnReadOnly = True ' open EXCEL file in read-only mode ' Open the EXCEL file and read the worksheet names into a collection Set colWorksheets = New Collection Set objWorkbook = objExcel.Workbooks.Open(strPathFile, , blnReadOnly, , _ strPassword) For lngCount = 1 To objWorkbook.Worksheets.Count colWorksheets.Add objWorkbook.Worksheets(lngCount).Name Next lngCount ' Close the EXCEL file without saving the file, and clean up the EXCEL objects objWorkbook.Close False Set objWorkbook = Nothing If blnEXCEL = True Then objExcel.Quit Set objExcel = Nothing ' Import the data from each worksheet into the table For lngCount = colWorksheets.Count To 1 Step -1 DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _ strTable, strPathFile, blnHasFieldNames, colWorksheets(lngCount) & "$" Next lngCount ' Delete the collection Set colWorksheets = Nothing ' Uncomment out the next code step if you want to delete the ' EXCEL file after it's been imported ' Kill strPathFile End Sub ):

RouterTestingModule

(通常情况下,会在import { MockComponent } from 'ng2-mock-component'; . . . TestBed.configureTestingModule({ declarations: [ MockComponent({ selector: 'a', inputs: [ 'routerLink', 'routerLinkActiveOptions' ] }), . . . ] 元素上使用routerLink,但会相应地调整其他组件的选择器。)

我想提到这个替代解决方案的第二个原因是,尽管它在许多规范文件中都很好用,但在一个案例中遇到了问题:

<a>

我无法弄清楚这个模拟器和我的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 是如何使用相同的选择器的,所以寻找替代方法让我来到@ raykrow的解决方案。

答案 10 :(得分:0)

如果您使用共享模块,只需将RouterModule添加到声明组件的模块中,并且不要忘记添加GOOGLE_APPLICATION_CREDENTIALS

从这里引用RouterLink does not work

答案 11 :(得分:-4)

我的解决方案很简单。我正在使用[href]而不是[routerLink]。我已经尝试了[routerLink]的所有解决方案。在我的情况下,它们都不起作用。

这是我的解决方案:

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

然后在TS文件中写入getPlanUrl函数。