摘要:在文件夾內創(chuàng)建,內容如下創(chuàng)建,內容如下使用安裝依賴在的頭部加入調用命令,同時在你的默認瀏覽器中打開。最后,我們更新下,給每個報道添加鏈接修改完畢地后,可以在瀏覽器中直接看到結果。
編者注:我們發(fā)現(xiàn)了有趣的系列文章《30天學習30種新技術》,正在翻譯,一天一篇更新,年終禮包。下面是第19天的內容。
到目前為止,我們這一系列文章涉及了Bower、AngularJS、GruntJS、PhoneGap和MeteorJS 這些JavaScript技術。今天我打算學習一個名為Ember的框架。本文將介紹如何用Ember創(chuàng)建一個單頁面的社交化書簽應用。本教程將包括兩篇:第1篇介紹客戶端代碼和用HTML 5本地存儲持久保存數(shù)據(jù),第2篇中我們將使用一個部署在OpenShift上的REST后端。過幾天我會寫第2篇。
應用我們將開發(fā)一個社交化書簽應用,允許用戶提交和分享鏈接。你可以在這里查看這個應用。這個應用可以做到:
當用戶訪問/時,他會看到以提交時間排序的報道列表。
當用戶訪問某個書簽時,例如#/stories/d6p88,用戶會看到關于這個報道的信息,例如是誰提交的,何時提交的,以及文章的摘要。
最后,當用戶通過#/story/new提交新報道時,內容會存儲在用戶瀏覽器的本地存儲上。
什么是Ember?Ember是一個客戶端的JavaScript MV* 框架,用來構建野心勃勃的web應用。它依賴于jQuery和Handlebars庫。如果你曾經(jīng)在Backbone下工作,那么你會發(fā)現(xiàn)Ember是一個武斷的Backbone,或者Backbone++。Ember可以為你完成很多事情,如果你遵循它的命名約定的話。Ember.js在這方面很突出。因此,如果我們在應用中加入了url路由和報道,那么我們就有了這些:
報道的模板
StoriesRoute
StoriesController
請參考命名約定文檔來理解Ember的命名約定。
Ember核心概念本節(jié)將介紹我們的示例應用中將涉及的四個EmberJS的核心概念:
模型:模型代表我們展示給用戶的應用領域內的對象。在上述例子中,一個報道就代表一個模型。報道,加上它的屬性,包括標題、url等,構成一個模型。模型可以通過jQuery加載服務器端的JSON數(shù)據(jù)的方式來獲取和更新,也可以通過Ember Data來獲取和更新。Ember Data是一個客戶端的ORM實現(xiàn),可以利用它方便地對底層的持久性存儲進行CRUD操作。Ember Data提供一個倉庫接口,可以借助提供的一些適配器配置。Ember Data提供的兩個核心適配器是RESTAdapter和FixtureAdapter。在本文中,我們將使用LocalStorage適配器,該適配器將數(shù)據(jù)持久化為 HTML 5 的LocalStorage。請參閱此文檔了解詳情。
路由器和路由:路由器指定應用的所有路由。路由器將URL映射到路由。例如,當一個用戶訪問/#/story/new的時候,將渲染newstory模板。該模板展現(xiàn)了一個HTML表單。用戶可通過創(chuàng)建Ember.Route子類來定制路由。在上述例子中,用戶訪問/#/story/new將渲染一個基于newstory模板的默認模型。NewStoryRoute會負責將默認的模型分配給newstory模板。請參閱文檔了解詳情。
控制器:控制器可以做兩件事——首先它裝飾路由返回的模型,接著它監(jiān)聽用戶執(zhí)行的行動。例如,當用戶提交報道的時候,NewStoryController負責通過Ember Data API將報道的數(shù)據(jù)持續(xù)化到存儲層。請參閱文檔了解詳情。
模版:模板向用戶展示應用的界面。每個應用都有一個默認的應用模板。
Ember的Chrome插件EmberJS提供了一個Chrome插件,因此調試ember應用很容易。這個插件可以在 chrome web store 下載安裝。可以查看Ember團隊做的視頻了解chrome插件的詳情。
Github倉庫今天的示例程序的代碼可從github取得。
第一步 下載新手套裝ember提供了一套新手裝備,因此開始使用框架非常簡單。新手套裝包括了需要用到的javascript文件(ember-*.js、jquery-*.js和handlerbars-*.js)以及示例應用。下載新手套裝,解壓縮,最后重命名為getbookmarks。
wget https://github.com/emberjs/starter-kit/archive/v1.1.2.zip unzip v1.1.2.zip mv starter-kit-1.1.2/ getbookmarks
在瀏覽器中打開index.html,你會看到如下頁面:
第二步 啟用GruntJS監(jiān)視這一步是可選的,不過如果你做了這步,那么你的生活質量將大大提高。如果你決定跳過這步,那么每次你做了改動之后都需要刷新瀏覽器。在第7天的文章,我討論了GruntJS的在線重載功能。我沒有在EmberJS里找到任何自動重載的功能,因此我決定使用GruntJS的livereload來提高效率。你需要Node、NPM和Grunt-CLI。請參考我第5天和第7天的文章了解詳情。
在getbookmarks文件夾內創(chuàng)建package.json,內容如下:
{ "name": "getbookmarks", "version": "0.0.1", "description": "GetBookMarks application", "devDependencies": { "grunt": "~0.4.1", "grunt-contrib-watch": "~0.5.3" } }
創(chuàng)建Gruntfile.js,內容如下:
module.exports = function(grunt) { grunt.initConfig({ watch :{ scripts :{ files : ["js/app.js","css/*.css","index.html"], options : { livereload : 9090, } } } }); grunt.loadNpmTasks("grunt-contrib-watch"); grunt.registerTask("default", []); };
使用npm安裝依賴:
npm install grunt --save-dev npm install grunt-contrib-watch --save-dev
在index.html的頭部加入:
調用grunt watch命令,同時在你的默認瀏覽器中打開index.html。
; grunt watch Running "watch" task Waiting...OK
修改index.html,無需刷新就能看到改變:
第三步 理解新手模板應用在新手模板中,除了css之外,有兩個和應用相關的文件——index.html和app.js。為了理解模板應用的作用,我們需要理解app.js。
App = Ember.Application.create(); App.Router.map(function() { // put your routes here }); App.IndexRoute = Ember.Route.extend({ model: function() { return ["red", "yellow", "blue"]; } });
解釋下以上的代碼:
第一行創(chuàng)建了一個Ember應用的實例。
使用App.Route.map定義應用的路由。每個Ember應用都有一個默認路由Index,綁定到/。所以,當調用/路由的時候,index模板將被渲染。index模板由index.html定義。感覺到了很多“約定大于配置”了吧?
在Ember中,每個模板都有一個model作為支持。路由負責制定哪個mobdel支持哪個模板。在上述app.js中,IndexRoute返回一個字符串數(shù)組,作為index模板的model。index模板迭代這個數(shù)組然后渲染一個列表。
第四步 移除新手模板代碼移除js/app.js中的代碼,然后用以下內容替換:
App = Ember.Application.create(); App.Router.map(function() { // put your routes here });
相應地,將index.html的內容替換為:
第五步 添加Twitter BootstrapGetBookMarks -- Share your favorite links online
我們將使用twitter bootstrap來給應用添加樣式。從官網(wǎng)下載twitter bootstrap包,然后復制bootstrap.css到css文件夾,同時復制字體文件夾。
接著在index.html中加入bootstrap.css,在頁首使用一個固定位置的導航條。
GetBookMarks -- Share your favorite links online
上述html中,代表我們的應用模板。應用模板使用{{outlet}}標簽為其他模板預留位置,其內容取決于url。
在css/style.css中加入下面的代碼。這會在正文上方添加一個40px的空白。這樣才能正確地渲染固定位置的導航條。
body{ padding-top: 40px; }第五步 提交新報道
我們將開始實現(xiàn)提交新報道的功能。Ember建議你圍繞著URL思考。當用戶訪問#/story/new的時候,會展示一個表單。
在App.Router.Map中增加一個綁定#/story/new的新路由:
App.Router.map(function() { this.resource("newstory" , {path : "story/new"}); });
接著我們在index.html中添加一個渲染表單的newstory模板:
訪問#/story/new即可查看表單:
接著我們在導航條中添加一個鏈接,這樣訪問報道提交表單就很容易。替換一下nav元素:
注意上面我們用{{#link-to}}創(chuàng)建了一個指向路由的鏈接。請參閱文檔了解詳情。
表單已經(jīng)有了,接下來要添加HTML 5本地存儲的功能。為了添加本地存儲支持,我們需要首先下載Ember Data和Local Storage Adapter JavaScript文件。將這些文件放在js/libs下。接著,在index.html中添加這些script標簽。
如前所述,Ember Data是一個客戶端的ORM實現(xiàn),它使在底層存儲進行CRUD操作很容易。這里我們將使用LSAdapter。在app.js中加入:
App.ApplicationAdapter = DS.LSAdapter.extend({ namespace: "stories" });
接著是定義model。一篇報道需要有url、title(標題)、fullname(提交報道的用戶的全名)、excerpt(摘要),以及SubmittedOn(日期)信息。在下面的模型中,我們使用了字符串和日期類型。適配器默認支持的屬性類型為字符串、數(shù)字、布爾值和日期。
App.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") });
接著我們編寫NewstoryController來持久化內容:
App.NewstoryController = Ember.ObjectController.extend({ actions :{ 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"); var story = store.createRecord("story",{ url : url, tags : tags, fullname : fullname, title : title, excerpt : excerpt, submittedOn : submittedOn }); story.save(); this.transitionToRoute("index"); } } });
以上代碼展示了如何從獲取表單中的值,然后使用store API在內存中創(chuàng)建記錄。為了在localstorage中存儲記錄,我們需要調用Story對象的save方法。最后,我們將用戶重定向到index路由。
接著我們測試下這個應用,創(chuàng)建一個新的報道,接著打開Chrome開發(fā)者工具,在資源區(qū)域你可以查看這則報道。
第六步 顯示所有報道接著我們要做的是,當用戶訪問首頁的時候,展示所有報道。
正如我之前提到的,路由負責詢問model。我們將加上IndexRoute,它會找出本地存儲中保存的所有報道。
App.IndexRoute = Ember.Route.extend({ model : function(){ var stories = this.get("store").findAll("story"); return stories; } });
每個路由支持一個模板。IndexRoute支持index模板,因此我們需要修改index.html:
現(xiàn)在訪問/,我們會看到一個報道的列表:
還有一個問題,報道沒有按照時間順序排列。我們將創(chuàng)建一個IndexController負責排序。我們指定依照submittedOn屬性倒序排列,以確保新的報道出現(xiàn)在上面。
App.IndexController = Ember.ArrayController.extend({ sortProperties : ["submittedOn"], sortAscending : false });
修改之后,我們會看到按照submittedOn屬性排序的報道。
第七步 查看多帶帶的報道最后要實現(xiàn)的功能是:用戶點擊某則報道的時候會看到詳細信息。我們加一個路由:
App.Router.map(function() { this.resource("index",{path : "/"},function(){ this.resource("story", { path:"/stories/:story_id" }); }); this.resource("newstory" , {path : "story/new"}); });
以上的代碼展示了如何嵌套路由。
:story_id部分叫做動態(tài)字段,因為相應的報道 id會被注入URL。
然后我們添加根據(jù)報道id獲取報道的StoryRoute。
App.StoryRoute = Ember.Route.extend({ model : function(params){ var store = this.get("store"); return store.find("story",params.story_id); } });
最后,我們更新下index.html,給每個報道添加鏈接:
修改完畢地后,可以在瀏覽器中直接看到結果。
第八步 為submittedOn日期添加格式Ember下有輔助函數(shù)的概念。所有Handlebars模板都可以調用輔助函數(shù)。
我們將使用moment.js庫為日期添加格式。將以下代碼加入index.html。
接著我們將定義我們的第一個輔助函數(shù),該函數(shù)將日期轉為人類可讀的形式:
Ember.Handlebars.helper("format-date", function(date){ return moment(date).fromNow(); });
最后我們在報道模板中加入format-data輔助函數(shù)。
報道頁面的效果如下:
今天就到這里了。持續(xù)反饋。
原文 Day 19: Ember--The Missing EmberJS Tutorial
翻譯 SegmentFault
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/77996.html
摘要:攝像拍照,濾鏡中文指南本文出自春哥個人博客作者黎躍春追時間的人簡介是推出的一個天挑戰(zhàn)。完整中文版指南及視頻教程在從零到壹全棧部落。這個新的對象表示指定的對象或對象。 Day19 - 攝像、拍照,濾鏡中文指南 本文出自:春哥個人博客作者:?黎躍春-追時間的人簡介:JavaScript30 是 Wes Bos 推出的一個 30 天挑戰(zhàn)。項目免費提供了 30 個視頻教程、30 個挑戰(zhàn)的起始文...
摘要:中文指南二作者簡介是推出的一個天挑戰(zhàn)。完整中文版指南及視頻教程在從零到壹全棧部落。第七天的練習是接著之前中文指南一的練習,繼續(xù)熟練數(shù)組的方法,依舊沒有頁面顯示效果,所以請打開瀏覽器的面板進行調試運行。 Day07 - Array Cardio 中文指南二 作者:?liyuechun 簡介:JavaScript30 是 Wes Bos 推出的一個 30 天挑戰(zhàn)。項目免費提供了 30 個...
摘要:實現(xiàn)可伸縮的圖片墻中文指南作者簡介是推出的一個天挑戰(zhàn)。現(xiàn)在你看到的是這系列指南的第篇。完整指南在從零到壹全棧部落。實現(xiàn)效果點擊任意一張圖片,圖片展開,同時從圖片上下兩方分別移入文字。 Day05 - Flex 實現(xiàn)可伸縮的圖片墻 中文指南 作者:?liyuechun 簡介:JavaScript30 是 Wes Bos 推出的一個 30 天挑戰(zhàn)。項目免費提供了 30 個視頻教程、30 ...
閱讀 2302·2021-09-30 09:47
閱讀 2219·2021-09-26 09:55
閱讀 2948·2021-09-24 10:27
閱讀 1540·2019-08-27 10:54
閱讀 967·2019-08-26 13:40
閱讀 2495·2019-08-26 13:24
閱讀 2419·2019-08-26 13:22
閱讀 1728·2019-08-23 18:38