- Day 1: Bower - 管理你的客户端依赖关系
- Day 2: AngularJS - 对 AngularJS 的初步认识
- Day 3: Flask - 使用 Python 和 OpenShift 进行即时 Web 开发
- Day 4:PredictionIO - 如何创建一个博客推荐器
- Day 5: GruntJS - 重复乏味的工作总会有人做(反正我不做)
- Day 6:在 Java 虚拟机上使用 Grails 进行快速 Web 开发
- Day 7: GruntJS 在线重载 提升生产率至新境界
- Day 8: Harp.JS - 现代静态 web 服务器
- Day 9: TextBlob - 对文本进行情感分析
- Day 10: PhoneGap - 开发手机应用如此简单
- Day 11: AeroGear 推送服务器:使应用的通知推送变得简单
- Day 12: OpenCV - Java 开发者的人脸检测
- Day 13: Dropwizard - 非常棒的 Java REST 服务器栈
- Day14:使用斯坦福 NER 软件包实现你自己的命名实体识别器(Named Entity Recognition,NER)
- Day 15:Meteor - 从零开始创建一个 Web 应用
- Day 16: Goose Extractor - 好用的文章提取工具
- Day 17: 使用 JBoss Forge 和 OpenShift 构建部署 JAVA EE 6 应用
- Day 18: BoilerPipe - Java 开发者的文章提取工具
- Day 19: EmberJS 入门指南
- Day 20: 斯坦福 CoreNLP - 用 Java 给 Twitter 进行情感分析
- Day 21:Docker 入门教程
- Day 22: 使用 Spring、MongoDB 和 AngularJS 开发单页面应用
- Day 23:使用 TimelineJS 构建精美的时间轴
- Day 24: 使用 Yeoman 自动构建 Ember 项目
- Day 25: 联合 Tornado、MongoDB 和 AngularJS 进行应用开发
- Day 26: TogetherJS - 让我们一起来编程!
- Day 27: Restify - 在 Node.js 中构建正确的 REST Web 服务
- Day 28: OpenShift 的 Eclipse 集成
- Day 29:编写你的第一个 Google Chrome 扩展程序
- Day 30: Play Framework - Java 开发者的梦想框架
Day 24: 使用 Yeoman 自动构建 Ember 项目
到目前为止,我们这个系列讨论了 Bower 、 AngularJS 、 GruntJS 、 PhoneGap 、 Meteor 、 Ember 和 TimelineJS 等 JavaScript 技术。今天的 《30 天学习 30 种新技术》 ,我决定学习前端开发的效率工具 Yeoman 。本文将首先介绍 Yeoman 的基本情况,接着我们会使用 Yeoman 开发一个 Ember 应用。本文不会介绍 EmberJS 的基本知识,所以请参考 day 19 。
Yeoman 是什么?
Yeoman 按照官方说法,它不只是一个工具,还是一个工作流。它其实包括了三个部分 yo、grunt、bower,分别用于项目的启动、文件操作、包管理。
- Yo: Yo 是一个项目初始化工具,可以生成一套启动某类项目必需的项目文件。
- GruntJS: GruntJS 是基于 JavaScript 的命令行构建工具,它可以帮助开发者们自动化重复性的工作。阅读 day 5 获取更多信息。
- Bower: Bower 是一个客户端技术的软件包管理器,它可用于搜索、安装和卸载如 JavaScript、HTML、CSS 之类的网络资源。阅读 day 1 获取更多信息。
我为什么关心 Yeoman
如果你需要说服自己学习 Yeoman,你可以读读 Yeoman 网站上的 whyyeoman 。
安装
使用 npm
安装:
npm install -g yeoman
安装 Yeoman Ember 生成器
Yeoman 依赖生成器为 web 项目提供支架。所有的现代 JavaScript MV* 框架都有相应的生成器。本文使用 Ember:
npm install -g generator-ember
我们将开发一个社交化书签应用,允许用户提交和分享链接。你可以在 这里 查看这个应用。这个应用和我们 day 19 开发的一样。
Github 仓库
今天的示例应用代码可从 Github 取得。
创建 Ember 应用
现在开始应用开发。首先创建项目目录,接着运行 yo ember
命令,它会询问你是否使用 Twitter Bootstrap。我习惯在自己的项目中使用 Bootstrap,所以我选了是。
; mkdir getbookmarks
; cd getbookmarks
; yo ember
_-----_
| |
|--(o)--| .--------------------------.
--------- | Welcome to Yeoman, |
( __ ) | ladies and gentlemen! |
/___A___\ '__________________________'
| ~ |
__'.___.'__
[?] Would you like to include Twitter Bootstrap for Sass? Yes
之后 Yeoman 会创建一个 Ember 应用,自动使用 bower
和 npm
安装依赖。
现在让我们看看 Yeoman 生成的 Ember 应用。应用有三个顶层目录: app
、 node_modules
和 test
。还有一些配置文件: .bowerrc
、 .gitignore
、 .jshintrc
、 Gruntfile.js
和 package.json
。目录结构如下所示。
所有的应用相关代码都在 app
目录下。目录结构遵循 Ember 的最佳实践。
bower_components
目录包括了客户端依赖,例如 Ember、Twitter Bootstrap,等等。Bower 在所有文件夹内安装所有依赖。image
目录包括了应用相关的图像。Yeoman 会优化image
目录内的图片。index.html
包含了所有的ember.js
依赖,所有的 bootstrap 依赖,以及build
注释(Gruntfile.js 可以据此替换或移除引用的未优化的脚本和样式表)。scripts
目录包含了 Ember 应用的 controller、view、model 和 route。styles
目录包含了应用相关的 css 文件。templates
目录包含了应用的 handlebar 模板。
现在我们可以启动预览服务器了:
grunt server
这会使用系统默认浏览器打开应用:
生成 Story Model
我们在 day19 中开发的 GetBookmarks 应用中创建了一个 Ember Model:Story。Yeoman 的次级生成器可以用来构建项目的部分,包括 model。运行如下命令生成 Story model:
yo ember:model Story
命令的输出如下:
create app/scripts/models/story_model.js
invoke ember:controller:/usr/local/lib/node_modules/generator-ember/model/index.js
create app/scripts/controllers/stories_controller.js
create app/scripts/controllers/story_edit_controller.js
create app/scripts/routes/stories_route.js
create app/scripts/routes/story_route.js
create app/scripts/routes/story_edit_route.js
invoke ember:view:/usr/local/lib/node_modules/generator-ember/controller/index.js
create app/scripts/views/story_view.js
create app/scripts/views/story_edit_view.js
create app/scripts/views/stories_view.js
create app/templates/story.hbs
create app/templates/story_edit.hbs
create app/templates/stories.hbs
create app/scripts/views/bound_text_field_view.js
invoke ember:router:/usr/local/lib/node_modules/generator-ember/controller/index.js
conflict app/scripts/router.js
[?] Overwrite app/scripts/router.js? overwrite
force app/scripts/router.js
这会在 app/scripts/models
目录下生成 story_model.js
,同时会生成相应的 view、controller 和 route。
修改下 story_model
:
Emberapp.Story = DS.Model.extend({
url : DS.attr('string'),
tags : DS.attr('string'),
fullname : DS.attr('string'),
title : DS.attr('string'),
excerpt : DS.attr('string'),
submittedOn : DS.attr('date')
});
重新启动 Grunt server 以便改动生效。
安装 Ember LocalStorage 适配器
我们将使用 HTML 5 LocalStorage 来存储数据。使用 bower 安装适配器。
bower install --save ember-localstorage-adapter
然后更新 index.html
页面,添加依赖:
<script src="bower_components/ember-localstorage-adapter/localstorage_adapter.js"></script>
同时更新 app/scripts/store.js
,配置应用使用 LSAdapter:
Getbookmarks.Store = DS.Store.extend();
Getbookmarks.ApplicationAdapter = DS.LSAdapter.extend({
namespace: 'stories'
});
更新路由
修改 router.js
:
Getbookmarks.Router.map(function () {
this.resource('index',{path : '/'});
this.resource('story', { path: '/story/:story_id' });
this.resource('story_edit', { path: '/story/new' });
});
提交新报道
我们首先添加用户访问 #/story/new
后会出现的表单。修改 app/templates/story_edit.hbs
:
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="title" class="col-sm-2 control-label">Title</label>
<div class="col-sm-10">
<input type="title" class="form-control" id="title" name="title" placeholder="Title of the link" required>
</div>
</div>
<div class="form-group">
<label for="excerpt" class="col-sm-2 control-label">Excerpt</label>
<div class="col-sm-10">
<textarea class="form-control" id="excerpt" name="excerpt" placeholder="Short description of the link" required></textarea>
</div>
</div>
<div class="form-group">
<label for="url" class="col-sm-2 control-label">Url</label>
<div class="col-sm-10">
<input type="url" class="form-control" id="url" name="url" placeholder="Url of the link" required>
</div>
</div>
<div class="form-group">
<label for="tags" class="col-sm-2 control-label">Tags</label>
<div class="col-sm-10">
<textarea id="tags" class="form-control" name="tags" placeholder="Comma seperated list of tags" rows="3" required></textarea>
</div>
</div>
<div class="form-group">
<label for="fullname" class="col-sm-2 control-label">Full Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="fullname" name="fullname" placeholder="Enter your Full Name like Shekhar Gulati" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success" {{action 'save'}}>Submit Story</button>
</div>
</div>
</form>
现在,访问 http://localhost:9000/#/story/new 可以看到提交报道的表单。
更新 StoryEditController
,将数据持续化入本地存储:
Getbookmarks.StoryEditController = Ember.ObjectController.extend({
save: function(){
var url = $('#url').val();
var tags = $('#tags').val();
var fullname = $('#fullname').val();
var title = $('#title').val();
var excerpt = $('#excerpt').val();
var submittedOn = new Date();
var store = this.get('store');
console.log('Store .. '+store);
var story = store.createRecord('story',{
url : url,
tags : tags,
fullname : fullname,
title : title,
excerpt : excerpt,
submittedOn : submittedOn
});
story.save();
this.transitionToRoute('index');
}
});
列出所有报道
接下来我们要实现的功能是在侧边栏展示报道列表。
在 application_route.js
,我们从本地存储获取所有的报道。
Getbookmarks.ApplicationRoute = Ember.Route.extend({
model : function(){
var stories = this.get('store').findAll('story');
return stories;
}
});
接着我们更新 application.hbs
,为每个报道的标题添加链接:
<div>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">GetBookmarks</a>
</div>
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="nav navbar-nav pull-right">
<li>{{#link-to 'story_edit'}}<span class="glyphicon glyphicon-plus"></span> Submit Story{{/link-to}}</li>
</ul>
</div>
</nav>
<div class="container" id="main">
<div class="row">
<div>
<div class="col-md-3">
<div class="well sidebar-nav">
<table class='table'>
<thead>
<tr><th>Recent Stories</th></tr>
</thead>
{{#each controller}}
<tr><td>
{{#link-to 'story' this}}
{{title}}
{{/link-to}}
</td></tr>
{{/each}}
</table>
</div>
</div>
<div class="col-md-9">
{{outlet}}
</div>
</div>
</div>
</div>
</div>
应用的用户界面会刷新。
查看单独的报道
最后要添加的功能是,用户访问 http://localhost:9000/#/story/:id 的时候可以查看单独的报道。 :id
对应于 story id
。修改 story_routejs
。
Getbookmarks.StoryRoute = Ember.Route.extend({
model : function(params){
var store = this.get('store');
return store.find('story',params.story_id);
}
});
修改 app/templates/story.hbs
:
<h1>{{title}}</h1>
<h2> by {{fullname}} <small class="muted">{{submittedOn}}</small></h2>
{{#each tagnames}}
<span class="label label-primary">{{this}}</span>
{{/each}}
<hr>
<p class="lead">
{{excerpt}}
</p>
为生产环境构建
最后,我们运行 grunt build
命令创建一个可分发的应用。 grunt build
命令将 app
目录下的源文件转换成 dist
目录下的可分发的应用。
grunt build
今天就这些。保持反馈。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论