热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[译]第二十四天:YeomanEmber缺失的指南

前言到目前为止,这个系列我们探讨了Bower,AngularJS,GruntJS,PhoneGap,Meteor,Ember和TimelineJSJavaScript
前言

到目前为止 ,这个系列我们探讨了Bower, AngularJS, GruntJS, PhoneGap, Meteor, Ember和TimelineJS Javascript技术。今天的30天挑战,我决定学习一款叫Yeoman的高效前端开发工具。本文,我们先了解Yeoman基础,然后用Yeoman开发一个Ember应用,这里不再讲EmberJS基础,你可参考第19天的博客。 

 

什么是Yeoman?

Yeoman是一个开源的高效客户端开发工具,它集成了工具和框架,有助于开发者快速高效并遵循最好的用户体验构建web应用。它的灵感来自Ruby on Rails 概念。Yeoman包含三个工具:

  1. Yo: 一个基架工具,当你需要开始新项目时为你生成所有架构模板,它避免了样板代码,利于开始新项目和配置grunt任务。
  2. Grunt: 基于Javascript的命令行构建工具,帮你自动完成需要重复的任务。你可以把它看作Javascript的Make或者Ant. 它可以执行像压缩,编译,单元测试,代码审查等任务,详细内容参考第5天关于GruntJS的博客。
  3. Bower: 客户端包管理工具,可用作搜索,安装,卸载web资源如Javascript, HTML和CSS. 它不是一款封闭的工具,为使用这种技术的开发者提供了大量选择。详细内容参考第1天关于Bower的博客。 
我为什么关注Yeoman?

如果你要说服自己学习Yeoman, 可以看看它网站上whyyeoman部分。 

前提准备

安装Yeoman之前先安装:

  1. Node: Yeoman需要NPM. NPM是一个node包管理,绑定在Nodejs安装中,所以,请从 http://nodejs.org 下载最新的node.js.
  2. Git: 需要git来从git仓库获取有些包的代码,所以,安装git. 
安装Yeoman

准备条件做好后,你可以输入以下命令安装yeoman.

$ npm install -g yeoman

View Code

以上命令会全局安装yeoman, -g 代表全局安装,如果你还没装Grunt和bower, 这也会给你安装好。 

安装Yeoman Ember Generator

Yeoman依赖Generators完成web基架,对现代Javascript MV*框架有多种generators, 我们用Ember generator. NPM用于安装generators.

$ npm install -g generator-ember.

View Code
程序用例

本文我们开发个网摘程序允许用户发布和分享链接,你可以查看在线程序,和第19天的一样,可以参考之前的用例来了解。 

Github仓库

今天的demo放在 github: day24-yeoman-emberjs-demo. 

创建Ember程序

讲完基础后我们来开始开发程序。 

在机器上新建目录,更改程序目录。

$ mkdir getbookmarks$ cd getbookmarks

View Code

然后运行yo ember, 它会问你是否想用Twitter Bootstrap, 一般我的程序都用它,所以我输入Yes.

$ yo ember_-----_| ||--(o)--| .--------------------------.--------- | Welcome to Yeoman, |( __ ) | ladies and gentlemen! |/___A___\ '__________________________'| ~ |__'.___.'__[?] Would you like to include Twitter Bootstrap for Sass? Yes

View Code

输入yes后,Yeoman会给出Ember程序架构,自动运行bower和npm安装程序所需的依赖。 

来看看Yeoman生成的Ember程序,这个程序有三个顶层目录:app, node_modules, test. 还有配置文件--.bowerrc, .gitignore, .jshintrc, Gruntfile.js, package.json. 程序结构如图。

 

所有程序特定代码都砸app目录,这个程序架构遵循Ember最佳体验。

 

  1. Bower_components目录存放所有客户端依赖,如Ember, Twitter Boostrap等,Bower在这个文件夹安装所有依赖,这个路径可以改到 .bowerrc文件夹。
  2. images目录存放所有特定图片,Yeoman优化这个目录的所有图片。
  3. Index.html文件包含所有ember.js依赖并按序排列,所有bootstrap依赖,和Gruntfile.js用于替换(或者移除)引用到non-optimized脚本或者HTML文件里的格式表单的'build'注释。
  4. scripts目录包含所有Ember程序控制器,视图,模型和路由。
  5. styles目录有程序指定的css文件,这个css导入bootstrap格式。
  6. templates目录包含程序handlebar模板。 

现在,运行启动内嵌的预览服务器,grunt服务器采用我第7天讲到的livereload.

$ grunt server

View Code

这会在默认浏览器里打开程序。

 

生成Story模型

第19天开发的GetBookmarks程序有一个Ember模型叫Story,Yeoman subgenerator可用于生成更小的Story模型,要生成Story模型,执行以下命令。

$ yo ember:model Story

View Code

输出如下。

create app/scripts/models/story_model.jsinvoke ember:controller:/usr/local/lib/node_modules/generator-ember/model/index.jscreate app/scripts/controllers/stories_controller.jscreate app/scripts/controllers/story_edit_controller.jscreate app/scripts/routes/stories_route.jscreate app/scripts/routes/story_route.jscreate app/scripts/routes/story_edit_route.jsinvoke ember:view:/usr/local/lib/node_modules/generator-ember/controller/index.jscreate app/scripts/views/story_view.jscreate app/scripts/views/story_edit_view.jscreate app/scripts/views/stories_view.jscreate app/templates/story.hbscreate app/templates/story_edit.hbscreate app/templates/stories.hbscreate app/scripts/views/bound_text_field_view.jsinvoke ember:router:/usr/local/lib/node_modules/generator-ember/controller/index.jsconflict app/scripts/router.js
[
?] Overwrite app/scripts/router.js? overwriteforce app/scripts/router.js

View Code

这会在app/scripts/models 目录下生成story_model.js, 连同还生成相应的视图,控制器和路由。如果你对此不太了解可参照我第19天的博客。 

用以下代码更新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')
});

View Code

请重启Grunt 服务器以使改动生效。 

安装Ember LocalStorage适配器

我们用HTML 5 LocalStorage存储数据,用bower安装适配器。

$ bower install --save ember-localstorage-adapter

View Code

然后更新index.html依赖

<script src&#61;"bower_components/ember-localstorage-adapter/localstorage_adapter.js">script>

View Code

同时用以下代码更新app/scripts/store.js.这会用LSAdapter(Local Storage Adapter)而不是FixtureAdapter配置程序。

Getbookmarks.Store &#61; DS.Store.extend();
Getbookmarks.ApplicationAdapter
&#61; DS.LSAdapter.extend({namespace: &#39;stories&#39;
});

View Code
更新路由

用以下代码替换router.js.

Getbookmarks.Router.map(function () {this.resource(&#39;index&#39;,{path : &#39;/&#39;});this.resource(&#39;story&#39;, { path: &#39;/story/:story_id&#39; });this.resource(&#39;story_edit&#39;, { path: &#39;/story/new&#39; });
});

View Code

以上代码&#xff0c;我们定义了三个路由。

  1. index路由对应的根路径。
  2. 查看独立文章用story路由。
  3. 用story_edit路由新建文章&#xff0c;当用户查看&#39;#/story/new&#39;, 一个表格会显示给用户。 
提交新Story

现在添加表格&#xff0c;用于用户打开&#39;#/story/new&#39;时显示&#xff0c;用以下代码更新 app/templates/story_edit.hbs. 

<form class&#61;"form-horizontal" role&#61;"form"><div class&#61;"form-group"><label for&#61;"title" class&#61;"col-sm-2 control-label">Titlelabel><div class&#61;"col-sm-10"><input type&#61;"title" class&#61;"form-control" id&#61;"title" name&#61;"title" placeholder&#61;"Title of the link" required>div>div><div class&#61;"form-group"><label for&#61;"excerpt" class&#61;"col-sm-2 control-label">Excerptlabel><div class&#61;"col-sm-10"><textarea class&#61;"form-control" id&#61;"excerpt" name&#61;"excerpt" placeholder&#61;"Short description of the link" required>textarea>div>div><div class&#61;"form-group"><label for&#61;"url" class&#61;"col-sm-2 control-label">Urllabel><div class&#61;"col-sm-10"><input type&#61;"url" class&#61;"form-control" id&#61;"url" name&#61;"url" placeholder&#61;"Url of the link" required>div>div><div class&#61;"form-group"><label for&#61;"tags" class&#61;"col-sm-2 control-label">Tagslabel><div class&#61;"col-sm-10"><textarea id&#61;"tags" class&#61;"form-control" name&#61;"tags" placeholder&#61;"Comma seperated list of tags" rows&#61;"3" required>textarea>div>div><div class&#61;"form-group"><label for&#61;"fullname" class&#61;"col-sm-2 control-label">Full Namelabel><div class&#61;"col-sm-10"><input type&#61;"text" class&#61;"form-control" id&#61;"fullname" name&#61;"fullname" placeholder&#61;"Enter your Full Name like Shekhar Gulati" required>div>div><div class&#61;"form-group"><div class&#61;"col-sm-offset-2 col-sm-10"><button type&#61;"submit" class&#61;"btn btn-success" {{action &#39;save&#39;}}>Submit Storybutton>div>div>form>

View Code

现在打开 http://localhost:9000/#/story/new 可以看到提交表格。 

更新 StoryEditController save功能&#xff0c;会把文章保存到本地存储中。

Getbookmarks.StoryEditController &#61; Ember.ObjectController.extend({save: function(){var url &#61; $(&#39;#url&#39;).val();var tags &#61; $(&#39;#tags&#39;).val();var fullname &#61; $(&#39;#fullname&#39;).val();var title &#61; $(&#39;#title&#39;).val();var excerpt &#61; $(&#39;#excerpt&#39;).val();var submittedOn &#61; new Date();var store &#61; this.get(&#39;store&#39;);console.log(&#39;Store .. &#39;&#43;store);var story &#61; store.createRecord(&#39;story&#39;,{url : url,tags : tags,fullname : fullname,title : title,excerpt : excerpt,submittedOn : submittedOn});story.save();this.transitionToRoute(&#39;index&#39;);}
});

View Code
列出所有文章

接下来的功能是实现在侧边栏显示文章列表。 

在application_route.js, 我们会从本地存储中获取所有文章。

Getbookmarks.ApplicationRoute &#61; Ember.Route.extend({model : function(){var stories &#61; this.get(&#39;store&#39;).findAll(&#39;story&#39;);return stories;}
});

View Code

接下来更新application.hbs加载文章标题和链接&#xff0c;用以下代码更新。

<div><nav class&#61;"navbar navbar-default navbar-fixed-top" role&#61;"navigation"><div class&#61;"navbar-header"><button type&#61;"button" class&#61;"navbar-toggle" data-toggle&#61;"collapse" data-target&#61;".navbar-ex1-collapse"><span class&#61;"sr-only">Toggle navigationspan><span class&#61;"icon-bar">span><span class&#61;"icon-bar">span><span class&#61;"icon-bar">span>button><a class&#61;"navbar-brand" href&#61;"#">GetBookmarksa>div><div class&#61;"collapse navbar-collapse navbar-ex1-collapse"><ul class&#61;"nav navbar-nav pull-right"><li>{{#link-to &#39;story_edit&#39;}}<span class&#61;"glyphicon glyphicon-plus">span> Submit Story{{/link-to}}li>ul>div>nav><div class&#61;"container" id&#61;"main"><div class&#61;"row"><div><div class&#61;"col-md-3"><div class&#61;"well sidebar-nav"><table class&#61;&#39;table&#39;><thead><tr><th>Recent Storiesth>tr>thead>{{#each controller}}<tr><td>{{#link-to &#39;story&#39; this}}{{title}}{{/link-to}}td>tr>{{/each}}table>div>div><div class&#61;"col-md-9">{{outlet}}div>div>div>div>
div>

View Code

程序界面会重新加载更新。 

查看单独文章

最后一个功能是当用户打开 http://localhost:9000/#/story/:id 会显示单独的文章&#xff0c;:id对应文章id, 用以下代码更新story_route.js.

Getbookmarks.StoryRoute &#61; Ember.Route.extend({model : function(params){var store &#61; this.get(&#39;store&#39;);return store.find(&#39;story&#39;,params.story_id);}
});

View Code

用以下代码更新 app/templates/story.hbs.

<h1>{{title}}h1>
<h2> by {{fullname}} <small class&#61;"muted">{{submittedOn}}small>h2>
{{#each tagnames}}
<span class&#61;"label label-primary">{{this}}span>
{{/each}}
<hr>
<p class&#61;"lead">{{excerpt}}
p>

View Code
构建产品

最后&#xff0c;运行grunt build命令生成一个分布式程序&#xff0c;grunt build命令使用app目录下的源代码文件&#xff0c;返回到dist下的分布式程序中。

$ grunt build

View Code

这就是今天的内容&#xff0c;继续给反馈吧。 

原文&#xff1a;https://www.openshift.com/blogs/day-24-yeoman-ember-the-missing-tutorial


转:https://www.cnblogs.com/endless-on/p/3517851.html



推荐阅读
  • 本文介绍了JavaScript进化到TypeScript的历史和背景,解释了TypeScript相对于JavaScript的优势和特点。作者分享了自己对TypeScript的观察和认识,并提到了在项目开发中使用TypeScript的好处。最后,作者表示对TypeScript进行尝试和探索的态度。 ... [详细]
  • Node.js学习笔记(一)package.json及cnpm
    本文介绍了Node.js中包的概念,以及如何使用包来统一管理具有相互依赖关系的模块。同时还介绍了NPM(Node Package Manager)的基本介绍和使用方法,以及如何通过NPM下载第三方模块。 ... [详细]
  • 程序员如何选择机械键盘轴体?红轴和茶轴对比
    本文介绍了程序员如何选择机械键盘轴体,特别是红轴和茶轴的对比。同时还介绍了U盘安装Linux镜像的步骤,以及在Linux系统中安装软件的命令行操作。此外,还介绍了nodejs和npm的安装方法,以及在VSCode中安装和配置常用插件的方法。最后,还介绍了如何在GitHub上配置SSH密钥和git的基本配置。 ... [详细]
  • centos php部署到nginx 404_NodeJS项目部署到阿里云ECS服务器全程详解
    本文转载自:http:www.kovli.com20170919ecs-deploy作者:Kovli本文详细介绍如何部署NodeJS项目到阿里云ECS上, ... [详细]
  • Node.js详细安装及环境配置
    1、下载安装根据自己电脑系统及位数选择,我这里选择windows64位.msi格式安装包(官网:https:odejs.orgzh-cndownload).msi和.zip格式区别 ... [详细]
  • 技术周报·2021-05-07-小编推荐向现代Javascript转型原文标题:Publish,ship,andinstallmodernJavaScriptforfaste ... [详细]
  • 大数据 (三) BI报表系统  superset 源码搭建开发环境
    大数据 (三) BI报表系统 superset 源码搭建开发环境 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • 问题内容npmERR!code1npmERR!pathE:\WebProject\jeecgboot-vue3\node_modules\gifsiclenpmERR!com ... [详细]
author-avatar
雪染苍原牛仔
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有