为什么给@Input 一个类型会破坏代码?
why does giving @Input a type breaks the code?
我注意到下面的代码中有一些有趣的地方。注释掉“:Hero”后,代码工作正常,但如果我取消注释并给英雄一个类型。它中断了——页面甚至不会呈现。据我所知, hero 无论如何都是隐含的 Hero 类型,为什么我不能明确说明。
@Input() hero/*: Hero*/;
为了演示这个问题,我有一个包含四个文件的简单项目。上面代码在hero-detail.component.ts:
结尾
import {Component, Input} from 'angular2/core';
import {Hero} from './hero';
@Component({
selector: 'my-hero-detail',
template: `
<div *ngIf="hero">
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="hero.name" placeholder="name"/>
</div>
</div>
`
})
export class HeroDetailComponent {
@Input() hero/*: Hero*/;
}
hero.ts定义英雄接口:
export interface Hero {
id: number;
name: string;
}
app.component.ts 与英雄交流-detail.component.ts:
import {Component} from 'angular2/core';
import {Hero} from './hero';
import {HeroDetailComponent} from './hero-detail.component';
@Component({
selector: 'my-app',
template:`
<h1>{{title}}</h1>
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="#hero of heroes"
[class.selected]="hero === selectedHero"
(click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
`,
styles:[`
.heroes {list-style-type: none; margin-left: 1em; padding: 0; width: 10em;}
.heroes li { cursor: pointer; position: relative; left: 0; transition: all 0.2s ease; }
.heroes li:hover {color: #369; background-color: #EEE; left: .2em;}
.heroes .badge {
font-size: small;
color: white;
padding: 0.1em 0.7em;
background-color: #369;
line-height: 1em;
position: relative;
left: -1px;
top: -1px;
}
.selected { background-color: #EEE; color: #369; }
`],
directives: [HeroDetailComponent]
})
export class AppComponent {
public title = 'Tour of Heroes';
public heroes = HEROES;
public selectedHero: Hero;
onSelect(hero: Hero) { this.selectedHero = hero; }
}
var HEROES: Hero[] = [
{ "id": 11, "name": "Mr. Nice" },
{ "id": 12, "name": "Narco" },
{ "id": 13, "name": "Bombasto" },
{ "id": 14, "name": "Celeritas" },
{ "id": 15, "name": "Magneta" },
{ "id": 16, "name": "RubberMan" },
{ "id": 17, "name": "Dynama" },
{ "id": 18, "name": "Dr IQ" },
{ "id": 19, "name": "Magma" },
{ "id": 20, "name": "Tornado" }
];
index.html 可能与问题最不相关,所以这里是 - 最后一个文件:
<!DOCTYPE html>
<html>
<head>
<title>Angular 2 QuickStart</title>
<!-- bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<!-- 1. Load libraries -->
<script src="https://rawgithub.com/systemjs/systemjs/0.19.6/dist/system.js"></script>
<script src="https://code.angularjs.org/tools/typescript.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.0/angular2-polyfills.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.0/Rx.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.0/http.dev.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.0/angular2.dev.js"></script>
<!-- 2. Configure SystemJS -->
<script>
System.config({
transpiler: 'typescript',
typescriptOptions: {emitDecoratorMetadata: true},
packages: {'app': {defaultExtension: 'ts'}}
});
System.import('app/boot')
.then(null, console.error.bind(console));
</script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>
这不是错误。类型仅在编写和编译过程中存在。在 JavaScript 中,输入装饰器被翻译成如下内容:
__decorate([core_1.Input("title"),
__metadata('design:type', Object)
], MyComponent.prototype, "title", void 0);
无论如何,您的编辑器或 Linter 应该就此警告您。
想通了,很有趣。
- 一旦我将"export interface Hero"更改为"export class Hero",问题就解决了。否则它会抱怨 "unexpected token export".
但是,如果我事先将 ts 文件转译为 js 文件,问题就会消失。仅当转译是即时完成时,问题才会存在。
packages: {'app': {defaultExtension: 'ts'}} // change 'ts' to 'js'
我注意到下面的代码中有一些有趣的地方。注释掉“:Hero”后,代码工作正常,但如果我取消注释并给英雄一个类型。它中断了——页面甚至不会呈现。据我所知, hero 无论如何都是隐含的 Hero 类型,为什么我不能明确说明。
@Input() hero/*: Hero*/;
为了演示这个问题,我有一个包含四个文件的简单项目。上面代码在hero-detail.component.ts:
结尾import {Component, Input} from 'angular2/core';
import {Hero} from './hero';
@Component({
selector: 'my-hero-detail',
template: `
<div *ngIf="hero">
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="hero.name" placeholder="name"/>
</div>
</div>
`
})
export class HeroDetailComponent {
@Input() hero/*: Hero*/;
}
hero.ts定义英雄接口:
export interface Hero {
id: number;
name: string;
}
app.component.ts 与英雄交流-detail.component.ts:
import {Component} from 'angular2/core';
import {Hero} from './hero';
import {HeroDetailComponent} from './hero-detail.component';
@Component({
selector: 'my-app',
template:`
<h1>{{title}}</h1>
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="#hero of heroes"
[class.selected]="hero === selectedHero"
(click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
`,
styles:[`
.heroes {list-style-type: none; margin-left: 1em; padding: 0; width: 10em;}
.heroes li { cursor: pointer; position: relative; left: 0; transition: all 0.2s ease; }
.heroes li:hover {color: #369; background-color: #EEE; left: .2em;}
.heroes .badge {
font-size: small;
color: white;
padding: 0.1em 0.7em;
background-color: #369;
line-height: 1em;
position: relative;
left: -1px;
top: -1px;
}
.selected { background-color: #EEE; color: #369; }
`],
directives: [HeroDetailComponent]
})
export class AppComponent {
public title = 'Tour of Heroes';
public heroes = HEROES;
public selectedHero: Hero;
onSelect(hero: Hero) { this.selectedHero = hero; }
}
var HEROES: Hero[] = [
{ "id": 11, "name": "Mr. Nice" },
{ "id": 12, "name": "Narco" },
{ "id": 13, "name": "Bombasto" },
{ "id": 14, "name": "Celeritas" },
{ "id": 15, "name": "Magneta" },
{ "id": 16, "name": "RubberMan" },
{ "id": 17, "name": "Dynama" },
{ "id": 18, "name": "Dr IQ" },
{ "id": 19, "name": "Magma" },
{ "id": 20, "name": "Tornado" }
];
index.html 可能与问题最不相关,所以这里是 - 最后一个文件:
<!DOCTYPE html>
<html>
<head>
<title>Angular 2 QuickStart</title>
<!-- bootstrap -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
<!-- 1. Load libraries -->
<script src="https://rawgithub.com/systemjs/systemjs/0.19.6/dist/system.js"></script>
<script src="https://code.angularjs.org/tools/typescript.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.0/angular2-polyfills.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.0/Rx.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.0/http.dev.js"></script>
<script src="https://code.angularjs.org/2.0.0-beta.0/angular2.dev.js"></script>
<!-- 2. Configure SystemJS -->
<script>
System.config({
transpiler: 'typescript',
typescriptOptions: {emitDecoratorMetadata: true},
packages: {'app': {defaultExtension: 'ts'}}
});
System.import('app/boot')
.then(null, console.error.bind(console));
</script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>
这不是错误。类型仅在编写和编译过程中存在。在 JavaScript 中,输入装饰器被翻译成如下内容:
__decorate([core_1.Input("title"),
__metadata('design:type', Object)
], MyComponent.prototype, "title", void 0);
无论如何,您的编辑器或 Linter 应该就此警告您。
想通了,很有趣。
- 一旦我将"export interface Hero"更改为"export class Hero",问题就解决了。否则它会抱怨 "unexpected token export".
但是,如果我事先将 ts 文件转译为 js 文件,问题就会消失。仅当转译是即时完成时,问题才会存在。
packages: {'app': {defaultExtension: 'ts'}} // change 'ts' to 'js'