在Angular 4中使用材料设计-数据绑定版本
在之前的文章中,我们讨论了如何在Angular 4中使用Material Design,并且我们已经完成了安装。现在,我想尝试一下在应用Material Design的同时进行数据绑定。
最一开始的陷阱
在这里有一个我遇到的非常棘手的问题,尽管有关于Angular4和Material Design安装的博客很多,但是很难找到同时讲述Angular4绑定的文章。可能是因为大家都已经熟悉了吧。也许对于初学者来说,同时学习Material Design和Angular可能不是非常常见的选择。所以,我决定参考一些基础教程来完成我的项目,但是我却一直陷入了项目错误中。
AngularJS Material というプロジェクトと、Angular Material は全く別のプロジェクトである。
这是一个事实。最初我错误地参考了AngularJS Material的代码,结果出现了找不到模块之类的错误,作为一个初学者的我感到非常绝望,突然间想换成React。当我搜索错误信息时,发现书写着”AngularJS Material和Angular Material是两个不同的项目”。唉,真是太混乱了。顺便说一下,AngularJS Material似乎是针对Angular 1.x的。所以,我们最好基本上参考Angular Material。基本上,它的文档很详细,很容易理解。
创建表单
我正在尝试创建一个基本的表单,并尝试将其绑定在一起。
请添加一个 @NgModule 注释错误
最初做时遇到了一个错误。JavaScript 错误有很多时候原因不太明确。
- “Please add a @NgModule annotation” error in 1.0.4. Works in 1.0.3.
详细内容在上述文章中,但具体来说,需要在tsconfig.json文件中添加path条目。如果是使用angular-cli的项目,则需要添加”Linked libraries”,并在tsconfig.json中指定链接路径。这个错误信息让人无从得知,真是令人痛苦。
"paths": {
"@angular/*": [
"..node_modules/@angular/*"
]
},
创建输入表单
先试着创建一个输入餐食的表单。首先,定义领域类。
export class Food {
name: string;
date: Date;
calorie: number;
protein: number;
carb: number;
fat: number;
meal_kind: FoodType;
}
为了简单起见,首先试试输入姓名和日期。
@Component({
selector: 'app-root',
templateUrl: './food-detail.component.html'
})
export class FoodDetailComponent {
food: Food;
constructor() {
this.food = new Food();
this.food.name = "Taro";
this.food.date = new Date();
}
title = 'Muscle Hack';
}
输入文字
为了实现文字输入,
Input
使用文本输入组件,需要按照上述页面的API说明,添加import { MatInputModule } from ‘@angular/material’;。具体而言,如下所示。与上篇文章一样,我将Material的导入分离出来,并在material.module.ts文件中进行。
import { NgModule } from '@angular/core';
import {
MdButtonModule,
MdMenuModule,
MdToolbarModule,
MdIconModule,
MdCardModule,
MatInputModule,
} from '@angular/material';
@NgModule({
imports: [
MdButtonModule,
MdMenuModule,
MdToolbarModule,
MdIconModule,
MdCardModule,
MatInputModule,
],
exports: [
MdButtonModule,
MdMenuModule,
MdToolbarModule,
MdIconModule,
MdCardModule,
MatInputModule,
]
})
export class MaterialModule {}
一般的的输入表单可以像这样处理。绑定方式与通常的Angular一样。
我参考了Angular示例-英雄之旅:第6部分进行编写。
<md-form-field class="example-full-width">
<input mdInput placeholder="Name" name="name" [(ngModel)]="food.name" disabled value="Ushio">
</md-form-field>
这样一来,画面显得非常冷淡。这让人感到很悲伤。
我想要让它看起来更好一些。那么,首先,让我们尝试添加一个工具栏。
<md-toolbar colo="primary">
<span>Msucle Hack</span>
</md-toolbar>
<md-form-field class="example-full-width">
<input mdInput placeholder="Name" name="name" [(ngModel)]="food.name" disabled value="Ushio">
</md-form-field>
呃呃。好朴素,跟我想的颜色不一样。怎么会这样!我本来还想着为什么呢,后来发现只是个错别字,颜色错了而已。
呃呃。太朴素了,跟我想的颜色不一样。为什么啊!一开始还在想着为什么呢,后来发现只是个打错字,颜色不对而已。
呃呃。太素净了,跟我想象的颜色不一样。怎么会这样!一开始还在想着为什么呢,后来发现原来只是错别字,颜色不一样。
<md-toolbar color="primary">
终于达到了我想要的颜色。
然而,尚未能夠達到樣品的水平,感覺很俗氣。對了,試試插入一張卡片。
看起来差不多了。
日期选择器
接下来,我想试着添加一个日期选择器。毕竟日期是一个有现成组件的部分,我想要使用它。
- Datepicker
参考同一个。但是这次,除了该页面 API 所需的模块之外,还需要其他的模块。其中包括 MdNativeDateModule。同样,material.module.ts 的描述也相应改变了。
import { NgModule } from '@angular/core';
import {
MdButtonModule,
MdMenuModule,
MdToolbarModule,
MdIconModule,
MdCardModule,
MatInputModule,
MdNativeDateModule,
MatDatepickerModule,
} from '@angular/material';
@NgModule({
imports: [
MdButtonModule,
MdMenuModule,
MdToolbarModule,
MdIconModule,
MdCardModule,
MatInputModule,
MdNativeDateModule,
MatDatepickerModule,
],
exports: [
MdButtonModule,
MdMenuModule,
MdToolbarModule,
MdIconModule,
MdCardModule,
MatInputModule,
MdNativeDateModule,
MatDatepickerModule,
]
})
export class MaterialModule {}
接下来,修改 food-detail.compent.html。
<md-toolbar color="primary">
<span>Msucle Hack</span>
</md-toolbar>
<md-card>
<form class="example-form">
<md-form-field class="example-full-width">
<input mdInput placeholder="Name" name="name" [(ngModel)]="food.name" disabled value="Ushio">
</md-form-field>
<md-form-field>
<input mdInput [(ngModel)]="food.date" name="date" [mdDatepicker]="myDatepicker">
<md-datepicker-toggle mdSuffix [for]="myDatepicker"></md-datepicker-toggle>
<md-datepicker #myDatepicker></md-datepicker>
</md-form-field>
</form>
</md-card>
这里没有特别需要注意的地方,只是刚刚新增了一个库。顺便提一下,如果从md-datepicker-toggle中删除mdSuffix,外观会变得奇怪,所以要加上mdSuffix,并调整位置。
嗯,看起来还不错。绑定得也很牢固。
嗯,不过按照日本的标准来看,显示可能有所不同。让我们指定一下语言环境吧。在 material.module.ts 文件中,添加以下内容。
providers: [
{provide: MAT_DATE_LOCALE, useValue: 'ja-JP'},
],
或者,将 food-detail.component.ts 文件中的 FoodDetailComponent 样式修改为以下方式。
export class FoodDetailComponent {
food: Food;
constructor(dateAdapter: DateAdapter<NativeDateAdapter>) {
dateAdapter.setLocale('ja-JP');
this.food = new Food();
this.food.name = "Taro";
this.food.date = new Date();
}
試驗後兩者均運行正常。
总结
很久没有碰JavaScript前端了,发现调试确实很麻烦。经常从调试信息中无法直接理解意思。所以还是npm start然后逐个添加组件来确认运行效果更好。原因是,一旦添加了东西,页面就会消失,出现令人沮丧的错误,但如果不按组件划分,调试就更困难了。这是一个小小的教训。
下一步,我想尝试使用enum来创建选项。
资源
-
- Angular 4 Material Tutorial
-
- Angular
-
- Angular Material
-
- “Please add a @NgModule annotation” error in 1.0.4. Works in 1.0.3.
- Angular 4 でマテリアルデザインを使う