到目前爲止 ,這個系列咱們探討了Bower, AngularJS, GruntJS, PhoneGap, Meteor, Ember和TimelineJS JavaScript技術。今天的30天挑戰,我決定學習一款叫Yeoman的高效前端開發工具。本文,咱們先了解Yeoman基礎,而後用Yeoman開發一個Ember應用,這裏再也不講EmberJS基礎,你可參考第19天的博客。 css
Yeoman是一個開源的高效客戶端開發工具,它集成了工具和框架,有助於開發者快速高效並遵循最好的用戶體驗構建web應用。它的靈感來自Ruby on Rails 概念。Yeoman包含三個工具:html
若是你要說服本身學習Yeoman, 能夠看看它網站上whyyeoman部分。 前端
安裝Yeoman以前先安裝:node
準備條件作好後,你能夠輸入如下命令安裝yeoman.git
$ npm install -g yeoman
以上命令會全局安裝yeoman, -g 表明全局安裝,若是你還沒裝Grunt和bower, 這也會給你安裝好。 github
Yeoman依賴Generators完成web基架,對現代JavaScript MV*框架有多種generators, 咱們用Ember generator. NPM用於安裝generators.web
$ npm install -g generator-ember.
本文咱們開發個網摘程序容許用戶發佈和分享連接,你能夠查看在線程序,和第19天的同樣,能夠參考以前的用例來了解。 npm
今天的demo放在 github: day24-yeoman-emberjs-demo. json
講完基礎後咱們來開始開發程序。 bootstrap
在機器上新建目錄,更改程序目錄。
$ mkdir getbookmarks
$ cd getbookmarks
而後運行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
輸入yes後,Yeoman會給出Ember程序架構,自動運行bower和npm安裝程序所需的依賴。
來看看Yeoman生成的Ember程序,這個程序有三個頂層目錄:app, node_modules, test. 還有配置文件--.bowerrc, .gitignore, .jshintrc, Gruntfile.js, package.json. 程序結構如圖。
全部程序特定代碼都砸app目錄,這個程序架構遵循Ember最佳體驗。
如今,運行啓動內嵌的預覽服務器,grunt服務器採用我第7天講到的livereload.
$ grunt server
這會在默認瀏覽器裏打開程序。
第19天開發的GetBookmarks程序有一個Ember模型叫Story,Yeoman subgenerator可用於生成更小的Story模型,要生成Story模型,執行如下命令。
$ 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, 連同還生成相應的視圖,控制器和路由。若是你對此不太瞭解可參照我第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') });
請重啓Grunt 服務器以使改動生效。
咱們用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(Local Storage Adapter)而不是FixtureAdapter配置程序。
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 save功能,會把文章保存到本地存儲中。
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對應文章id, 用如下代碼更新story_route.js.
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
這就是今天的內容,繼續給反饋吧。
原文:https://www.openshift.com/blogs/day-24-yeoman-ember-the-missing-tutorial