使用CLI,Webpack和Github页面。
从一开始就使用angular-cli和webpack的Angular2 Villains教程。
这是第1部分。
如果您有任何输入或改进,请分叉,修复并添加拉取请求:https://github.com/wingsuitist/villains/
7.组成
让我们将其分解为有用的组件。
您可以让您的应用保持运行状态,并在每一步后查看其状态。 它应该自动重新加载。
这部分的最终来源:https://github.com/wingsuitist/villains/tree/v7.4.0
7.1。 生成编辑组件
创建组件的最简单方法是使用angular-cli(您可能会认识到,我们非常喜欢此工具):
cd src / app /
ng生成组件反派
这样,您将获得一个包含您的组件的新文件夹,其中包括css,html,TypeScript类,甚至是测试文件(spec.ts)。
但是,如果您检查git status,您将看到它还将您的组件添加到app.module.ts文件中以使其立即可用。
7.2。 命名约定
如果您看一下TypeScript组件,您将了解一些有关命名约定的信息:
@零件({
选择器:“ vil-villain-edit”,
templateUrl:“ ./ villain-edit.component.html”,
styleUrls:['./ villain-edit.component.css']
})
导出类VillainEditComponent实现OnInit {
在这种情况下,您将从上至下首先看到选择器,该选择器指向HTML标签。 您可能已经从单词选择器中猜测到,这允许您使用多个标签。 您还可以使用选择器:“。vil-villain-edit”,该选择器允许您通过具有
之类的任何标签来调用此组件。
现在,为什么在选择器前面有一个vil? 这是由于我们在本教程开始时定义的前缀。 Angular-cli将使用此前缀作为选择器,以确保没有其他标签干扰您的模块。 这是模板中的一种名称空间替代。
然后,您会看到带有连字符的文件名,其中连字符分隔了组件名称的各个部分。
最后但并非最不重要的一点是,您会看到使用大写驼峰字母的类名。
在样式指南中,有很多很好的解释说明了为什么选择这些约定。 但是现在很高兴知道angular-cli团队正在阻止我们并确保一切正确。
7.3。 准备输入
在我们的新组件中,我们还将需要Villain对象将其移交给视图。
为此,我们首先必须将Villain模型类导入到新组件中:
从“ ../shared”导入{反派}
AppComponent将通过所谓的输入将反派角色提供给VillainEditComponent。 此输入必须从angular-cli已经生成的语句中的villain-edit.component.ts中的angular / core导入:
从'@ angular / core'导入{Component,OnInit,Input};
现在,我们可以将Villain属性声明为Input属性:
导出类VillainEditComponent实现OnInit {
@Input()
恶棍:恶棍;
现在,当我们在某处使用标记时,它可以用作属性。
7.4。 移动编辑表单
首先,我们将编辑表单从app.component.html移到villain-edit.component.html。 一切保持不变,就像我们以前拥有反派对象一样。
在app.component.html中,我们添加带有@Input属性反派的新的单独编辑Component:
现在,如果您返回浏览器,将看到当前状态,该状态应与以前相同。
8.服务
我们仍在app.component.ts中使用静态反派。 将来我们希望从其他不同组件访问它们,并且也可能从服务器获取它们时,我们构建了服务。
8.1。 创建并注入服务类
angular 2中的服务是带有@Injectable()装饰器的常规类,用于为依赖项注入做准备。 (在这里您可以找到有关装饰器工作原理的精彩视频:)
但是,为什么要麻烦,让我们用angular-cli生成我们的服务:
cd src / app /
ng生成服务共享/恶意
这将生成一个新文件villain.service.ts,其中包含最少的可注入服务:
从“ @ angular / core”导入{可注射};
@Injectable()
出口等级VillainService {
builder(){}
}
为了简化导入服务,我们将其添加到shared / index.ts中:
从'./villain.model'导出*;
从'./villain.service'导出*;
现在,我们必须在app.compontent.ts中使其可供使用。 我们首先将其添加到要从./shared文件夹导入的内容列表中:
从“ @ angular / core”导入{组件};
从“ ./shared”导入{Villain,VillainService};
然后,将它作为提供程序添加到@Component()装饰器中。 最后,我们添加具有TypeScript功能的构造函数方法,以将注入的对象直接定义为AppCompontent的属性:
@零件({
选择器:“ vil-root”,
templateUrl:“ ./ app.component.html”,
styleUrls:['./app.component.css'],
提供者:[VillainService]
})
导出类AppComponent {
title =“恶棍团结!”;
恶棍=村庄;
恶棍:恶棍;
构造函数(私有villainService:VillainService){}
现在,我们可以通过this.villainService访问它。
8.2。 让我们得到一些恶棍
让我们将反派数组从app.component.ts移到villain.service.ts,并添加getVillains()函数以将其返回。 不要忘记导入小人。
从“ @ angular / core”导入{可注射};
从“ ./villain.model”导入{反派};
const VILLAINS:恶棍[] = [
{id:1,别名:“ Rebooter”,电源:“ Random Updates”},
{id:2,别名:“ Break Changer”,功率:“ APIrushing”},
{id:3,别名:“ Not-Tester”,功能:“在产品上编辑”},
{id:4,别名:“ Super Spamer”,功率:“ Mail Fludding”},
{id:5,别名:“太太。 DDOS”,电源:“服务过度使用”},
{id:6,别名:“特洛伊木马”,功率:“远程控制”},
{id:7,别名:“ Randzombie”,功率:“ Encryptor”},
{id:8,别名:“ Leacher”,功率:“ Net Overload”},
{id:23,别名:“ Captain Spaghetticoder”,功率:“ Bug Creator”}
];
@Injectable()
出口等级VillainService {
builder(){}
getVillains():恶棍[] {
返回村庄;
}
}
现在,我们要在AppComponent中使用该服务。 正确使用它的地方是所谓的OnInit生命周期挂钩。 为了使angular2调用我们的ngOnInit()方法,我们将其导入并在AppComponent中实现:
从'@ angular / core'导入{Component,OnInit};
从“ ./shared”导入{Villain,VillainService};
@零件({
选择器:“ vil-root”,
templateUrl:“ ./ app.component.html”,
styleUrls:['./app.component.css'],
提供者:[VillainService]
})
导出类AppComponent实现OnInit {
title =“恶棍团结!”;
恶棍:恶棍;
小人:小人[];
构造函数(私有villainService:VillainService){}
ngOnInit():void {
this.villains = this.villainService.getVillains();
}
onSelect(反面:反派):void {
this.villain =恶棍;
}
}
9.路由
我们想添加一个单独的视图,以训练我们了解每个恶棍的力量。 为此,我们需要在视图之间切换的可能性,这可以通过路由解决。
将为angular-cli提供路由支持。 由于使用了新的路由器版本,因此已将其删除,并将在以后集成。 (请告诉我在正式版本中尽快对其进行更新。)
9.1单独列表视图
让我们为“恶棍列表”添加一个新组件,以将其与AppComponent分开:
光盘src / app
ng生成组件反派列表
不,我们将代码从AppComponent移到坏人列表/组件。
您的app.component.ts应该如下所示:
从'@ angular / core'导入{Component,OnInit};
@零件({
选择器:“ vil-root”,
templateUrl:“ ./ app.component.html”,
styleUrls:['./ app.component.css']
})
导出类AppComponent实现OnInit {
Constructor(){}
ngOnInit():void {
}
}
您的villain-list.component.ts应该如下所示:
从'@ angular / core'导入{Component,OnInit};
从“ ../shared”导入{Villain,VillainService};
@零件({
选择器:“ vil-villain-list”,
templateUrl:“ ./ villain-list.component.html”,
styleUrls:['./villain-list.component.css'],
提供者:[VillainService]
})
导出类VillainListComponent实现OnInit {
title =“恶棍团结!”;
恶棍:恶棍;
小人:小人[];
构造函数(私有villainService:VillainService){}
ngOnInit():void {
this.villains = this.villainService.getVillains();
}
onSelect(反面:反派):void {
this.villain =恶棍;
}
}
您可以将整个html从应用程序组件剪切并粘贴到小人列表。
现在,您可以将反派列表组件添加到app.component.html中,以确保一切正常:
9.2基本路由
我们将在新文件app.routing.ts中管理路线:
从“ @ angular / core”导入{ModuleWithProviders};
从'@ angular / router'导入{Routes,RouterModule};
从'./villain-list/villain-list.component'导入{VillainListComponent};
const appRoutes:路线= [
{
路径:“恶棍”,
组件:VillainListComponent
}
];
导出常量路由:ModuleWithProviders = RouterModule.forRoot(appRoutes);
这将为路径villains /添加第一条路线,该路线将加载VillainListComponent。 为了利用此路由,我们稍后导出一个路由ModuleWithProviders,以将其用于AppComponent中的路由。
现在,将路由添加到app.module.ts中的模块中:
从“ ./app.routing”导入{路由};
// ...
@NgModule({
// ...
进口:[
BrowserModule,
表格模块
HttpModule,
路由
现在,除了直接在我们的app.component.html中加载VillainListComponent之外,我们将使用router-outlet显示路由器想要加载的内容:
如果现在查看浏览器,将会看到一个JavaScript错误,该错误没有路由匹配,并且什么也没有显示。 如果调用URLhttp://:// localhost:4200 / villains,则会看到该应用程序。
9.3导航
现在,将导航添加到我们的app.component.html中:
然后将默认路由添加到我们的app.routing.ts:
const appRoutes:路线= [
{
路径:“恶棍”,
组件:VillainListComponent
},
{
路径:“ **”,
组件:VillainListComponent
}
现在我们有了一个导航,无论如何加载了VillainListComponent。
9.3添加并布线电源组件
因此,让我们现在添加一个空的PowersComponent并路由到它:
光盘src / app
ng产生分量功率
将其添加到我们的路由配置中:
// ...
从'./villain-list/villain-list.component'导入{VillainListComponent};
从“ ./powers/powers.component”导入{PowersComponent};
const appRoutes:路线= [
{
路径:“权力”,
组件:PowersComponent
},
// ...
现在我们可以在组件之间导航。
9.4重定向
要获得一个清晰的网址,我们可以将/重定向到恶棍:
{
路径:“,
redirectTo:'恶棍',
pathMatch:“已满”
},
路由器从上到下遍历appRouters数组,以匹配每种情况。 一旦找到第一个匹配项,它将按照配置执行它。
10.学习力量
因此,让我们学习每个恶棍的力量,以便我们准备捍卫自己。
10.1。 显示随机力量
首先,我们需要注入VillainService来在powers.component.ts中获取恶棍:
从'@ angular / core'导入{Component,OnInit};
从“ ../shared”导入{Villain,VillainService};
@零件({
选择器:“民权”,
templateUrl:“ ./ powers.component.html”,
styleUrls:['./powers.component.css'],
提供者:[VillainService]
})
导出类PowersComponent实现OnInit {
构造函数(私有villainService:VillainService){}
然后我们要为测验随机抽取一个恶棍:
导出类PowersComponent实现OnInit {
小人:小人[];
randomVillain:恶棍;
构造函数(私有villainService:VillainService){}
ngOnInit(){
this.villains = this.villainService.getVillains();
让randomKey:number = Math.floor(Math.random()* this.villains.length);
this.randomVillain = this.villains [randomKey];
}
现在,我们可以在powers.component.html中显示此反派力量:
猜小人:
{{randomVillain.power}}
10.2。 共享小人服务(优化)
Angular使用所谓的区域,每次将服务添加到Component中的提供程序列表时,它都会创建此服务的单独实例。
没有理由为我们的组件创建VillainService的单独实例。
因此,让我们删除提供程序:从VillainListComponent和PowersComponent中删除[VillainService],并将其添加到app.module.ts中的@NgModule中。 我们还需要将其导入到app.module.ts中,并且必须在每个Component中保留导入以及构造函数的参数。
10.3。 创建getRandomVillain()(优化)
即使在数组中查找随机项只是一小段代码,我们也应将其移出组件。 也许稍后,我们将更改如何接收随机小人的实现。
因此,让我们将getRandomVillain函数添加到我们的villain.service.ts中:
getRandomVillain():反派{
让反派= this.getVillains();
让randomKey:number = Math.floor(Math.random()* villains.length);
返回恶棍[randomKey];
}
让我们在PowersComponent中使用它:
ngOnInit(){
this.villains = this.villainService.getVillains();
这个随机的恶棍
= this.villainService.getRandomVillain();
}
10.4。 选择匹配的恶棍
现在让我们列出恶棍,让用户选择匹配的恶棍,根据我们的成功显示我们的分数和一条消息:
猜小人:
{{randomVillain.power}}
哪个小人有这种能力?
{{message}}
{{score}}
并创建匹配方法,该方法将获得一个新的随机恶棍,增加或重置我们的分数并显示一条消息:
导出类PowersComponent实现OnInit {
小人:小人[];
randomVillain:恶棍;
得分:数字= 0;
讯息:字串;
构造函数(私有villainService:VillainService){}
ngOnInit(){
this.villains = this.villainService.getVillains();
this.randomVillain = this.villainService.getRandomVillain();
}
选择反派(反派:反派){
if(this.randomVillain.id == villain.id){
this.score ++;
this.message ='正确!';
}其他{
this.score = 0;
this.message ='错误-重新开始。
}
this.randomVillain = this.villainService.getRandomVillain();
}
}