日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

Day 19: EmberJS 入门指南

發(fā)布時(shí)間:2025/3/21 javascript 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Day 19: EmberJS 入门指南 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

到目前為止,我們這一系列文章涉及了Bower、AngularJS、GruntJS、PhoneGap和MeteorJS 這些JavaScript技術(shù)。今天我打算學(xué)習(xí)一個(gè)名為Ember的框架。本文將介紹如何用Ember創(chuàng)建一個(gè)單頁(yè)面的社交化書(shū)簽應(yīng)用。本教程將包括兩篇:第1篇介紹客戶端代碼和用HTML 5本地存儲(chǔ)持久保存數(shù)據(jù),第2篇中我們將使用一個(gè)部署在OpenShift上的REST后端。過(guò)幾天我會(huì)寫(xiě)第2篇。

應(yīng)用

我們將開(kāi)發(fā)一個(gè)社交化書(shū)簽應(yīng)用,允許用戶提交和分享鏈接。你可以在這里查看這個(gè)應(yīng)用。這個(gè)應(yīng)用可以做到:

  • 當(dāng)用戶訪問(wèn)/時(shí),他會(huì)看到以提交時(shí)間排序的報(bào)道列表。

  • 當(dāng)用戶訪問(wèn)某個(gè)書(shū)簽時(shí),例如#/stories/d6p88,用戶會(huì)看到關(guān)于這個(gè)報(bào)道的信息,例如是誰(shuí)提交的,何時(shí)提交的,以及文章的摘要。

  • 最后,當(dāng)用戶通過(guò)#/story/new提交新報(bào)道時(shí),內(nèi)容會(huì)存儲(chǔ)在用戶瀏覽器的本地存儲(chǔ)上。

什么是Ember?

Ember是一個(gè)客戶端的JavaScript MV* 框架,用來(lái)構(gòu)建野心勃勃的web應(yīng)用。它依賴于jQuery和Handlebars庫(kù)。如果你曾經(jīng)在Backbone下工作,那么你會(huì)發(fā)現(xiàn)Ember是一個(gè)武斷的Backbone,或者Backbone++。Ember可以為你完成很多事情,如果你遵循它的命名約定的話。Ember.js在這方面很突出。因此,如果我們?cè)趹?yīng)用中加入了url路由和報(bào)道,那么我們就有了這些:

  • 報(bào)道的模板
  • StoriesRoute
  • StoriesController

請(qǐng)參考命名約定文檔來(lái)理解Ember的命名約定。

Ember核心概念

本節(jié)將介紹我們的示例應(yīng)用中將涉及的四個(gè)EmberJS的核心概念:

  • 模型:模型代表我們展示給用戶的應(yīng)用領(lǐng)域內(nèi)的對(duì)象。在上述例子中,一個(gè)報(bào)道就代表一個(gè)模型。報(bào)道,加上它的屬性,包括標(biāo)題、url等,構(gòu)成一個(gè)模型。模型可以通過(guò)jQuery加載服務(wù)器端的JSON數(shù)據(jù)的方式來(lái)獲取和更新,也可以通過(guò)Ember Data來(lái)獲取和更新。Ember Data是一個(gè)客戶端的ORM實(shí)現(xiàn),可以利用它方便地對(duì)底層的持久性存儲(chǔ)進(jìn)行CRUD操作。Ember Data提供一個(gè)倉(cāng)庫(kù)接口,可以借助提供的一些適配器配置。Ember Data提供的兩個(gè)核心適配器是RESTAdapter和FixtureAdapter。在本文中,我們將使用LocalStorage適配器,該適配器將數(shù)據(jù)持久化為 HTML 5 的LocalStorage。請(qǐng)參閱此文檔了解詳情。

  • 路由器和路由:路由器指定應(yīng)用的所有路由。路由器將URL映射到路由。例如,當(dāng)一個(gè)用戶訪問(wèn)/#/story/new的時(shí)候,將渲染newstory模板。該模板展現(xiàn)了一個(gè)HTML表單。用戶可通過(guò)創(chuàng)建Ember.Route子類來(lái)定制路由。在上述例子中,用戶訪問(wèn)/#/story/new將渲染一個(gè)基于newstory模板的默認(rèn)模型。NewStoryRoute會(huì)負(fù)責(zé)將默認(rèn)的模型分配給newstory模板。請(qǐng)參閱文檔了解詳情。

  • 控制器:控制器可以做兩件事——首先它裝飾路由返回的模型,接著它監(jiān)聽(tīng)用戶執(zhí)行的行動(dòng)。例如,當(dāng)用戶提交報(bào)道的時(shí)候,NewStoryController負(fù)責(zé)通過(guò)Ember Data API將報(bào)道的數(shù)據(jù)持續(xù)化到存儲(chǔ)層。請(qǐng)參閱文檔了解詳情。

  • 模版:模板向用戶展示應(yīng)用的界面。每個(gè)應(yīng)用都有一個(gè)默認(rèn)的應(yīng)用模板。

  • Ember的Chrome插件

    EmberJS提供了一個(gè)Chrome插件,因此調(diào)試ember應(yīng)用很容易。這個(gè)插件可以在 chrome web store 下載安裝??梢圆榭碋mber團(tuán)隊(duì)做的視頻了解chrome插件的詳情。

    Github倉(cāng)庫(kù)

    今天的示例程序的代碼可從github取得。

    第一步 下載新手套裝

    ember提供了一套新手裝備,因此開(kāi)始使用框架非常簡(jiǎn)單。新手套裝包括了需要用到的javascript文件(ember-*.js、jquery-*.js和handlerbars-*.js)以及示例應(yīng)用。下載新手套裝,解壓縮,最后重命名為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

    在瀏覽器中打開(kāi)index.html,你會(huì)看到如下頁(yè)面:

    第二步 啟用GruntJS監(jiān)視

    這一步是可選的,不過(guò)如果你做了這步,那么你的生活質(zhì)量將大大提高。如果你決定跳過(guò)這步,那么每次你做了改動(dòng)之后都需要刷新瀏覽器。在第7天的文章,我討論了GruntJS的在線重載功能。我沒(méi)有在EmberJS里找到任何自動(dòng)重載的功能,因此我決定使用GruntJS的livereload來(lái)提高效率。你需要Node、NPM和Grunt-CLI。請(qǐng)參考我第5天和第7天的文章了解詳情。

    在getbookmarks文件夾內(nèi)創(chuàng)建package.json,內(nèi)容如下:

    {"name": "getbookmarks","version": "0.0.1","description": "GetBookMarks application","devDependencies": {"grunt": "~0.4.1","grunt-contrib-watch": "~0.5.3"} }

    創(chuàng)建Gruntfile.js,內(nèi)容如下:

    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的頭部加入:

    <script src="http://localhost:9090/livereload.js"></script>

    調(diào)用grunt watch命令,同時(shí)在你的默認(rèn)瀏覽器中打開(kāi)index.html。

    ; grunt watch Running "watch" task Waiting...OK

    修改index.html,無(wú)需刷新就能看到改變:

    第三步 理解新手模板應(yīng)用

    在新手模板中,除了css之外,有兩個(gè)和應(yīng)用相關(guān)的文件——index.html和app.js。為了理解模板應(yīng)用的作用,我們需要理解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)建了一個(gè)Ember應(yīng)用的實(shí)例。

  • 使用App.Route.map定義應(yīng)用的路由。每個(gè)Ember應(yīng)用都有一個(gè)默認(rèn)路由Index,綁定到/。所以,當(dāng)調(diào)用/路由的時(shí)候,index模板將被渲染。index模板由index.html定義。感覺(jué)到了很多“約定大于配置”了吧?

  • 在Ember中,每個(gè)模板都有一個(gè)model作為支持。路由負(fù)責(zé)制定哪個(gè)mobdel支持哪個(gè)模板。在上述app.js中,IndexRoute返回一個(gè)字符串?dāng)?shù)組,作為index模板的model。index模板迭代這個(gè)數(shù)組然后渲染一個(gè)列表。

  • 第四步 移除新手模板代碼

    移除js/app.js中的代碼,然后用以下內(nèi)容替換:

    App = Ember.Application.create();App.Router.map(function() {// put your routes here });

    相應(yīng)地,將index.html的內(nèi)容替換為:

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>GetBookMarks -- Share your favorite links online</title><link rel="stylesheet" href="css/normalize.css"><link rel="stylesheet" href="css/style.css"><script src="http://localhost:9090/livereload.js"></script> </head> <body><script type="text/x-handlebars">{{outlet}}</script><script type="text/x-handlebars" data-template-name="index"></script><script src="js/libs/jquery-1.9.1.js"></script><script src="js/libs/handlebars-1.0.0.js"></script><script src="js/libs/ember-1.1.2.js"></script><script src="js/app.js"></script></body> </html>

    第五步 添加Twitter Bootstrap

    我們將使用twitter bootstrap來(lái)給應(yīng)用添加樣式。從官網(wǎng)下載twitter bootstrap包,然后復(fù)制bootstrap.css到css文件夾,同時(shí)復(fù)制字體文件夾。

    接著在index.html中加入bootstrap.css,在頁(yè)首使用一個(gè)固定位置的導(dǎo)航條。

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>GetBookMarks -- Share your favorite links online</title><link rel="stylesheet" href="css/normalize.css"><link rel="stylesheet" type="text/css" href="css/bootstrap.css"><link rel="stylesheet" href="css/style.css"><script src="http://localhost:9090/livereload.js"></script> </head> <body><script type="text/x-handlebars"><nav class="navbar navbar-default navbar-fixed-top" role="navigation"><div class="container"><div class="navbar-header"><a class="navbar-brand" href="#">GetBookMarks</a></div></div></nav><div id="main" class="container">{{outlet}}</div></script><script type="text/x-handlebars" data-template-name="index"></script><script src="js/libs/jquery-1.9.1.js"></script><script src="js/libs/handlebars-1.0.0.js"></script><script src="js/libs/ember-1.1.2.js"></script><script src="js/app.js"></script></body> </html>

    上述html中,<script type="text/x-handlebars">代表我們的應(yīng)用模板。應(yīng)用模板使用{{outlet}}標(biāo)簽為其他模板預(yù)留位置,其內(nèi)容取決于url。

    在css/style.css中加入下面的代碼。這會(huì)在正文上方添加一個(gè)40px的空白。這樣才能正確地渲染固定位置的導(dǎo)航條。

    body{padding-top: 40px; }

    第五步 提交新報(bào)道

    我們將開(kāi)始實(shí)現(xiàn)提交新報(bào)道的功能。Ember建議你圍繞著URL思考。當(dāng)用戶訪問(wèn)#/story/new的時(shí)候,會(huì)展示一個(gè)表單。

    在App.Router.Map中增加一個(gè)綁定#/story/new的新路由:

    App.Router.map(function() {this.resource('newstory' , {path : 'story/new'}); });

    接著我們?cè)趇ndex.html中添加一個(gè)渲染表單的newstory模板:

    <script type="text/x-handlebars" id="newstory"><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></script>

    訪問(wèn)#/story/new即可查看表單:

    接著我們?cè)趯?dǎo)航條中添加一個(gè)鏈接,這樣訪問(wèn)報(bào)道提交表單就很容易。替換一下nav元素:

    <nav class="navbar navbar-default navbar-fixed-top navbar-inverse" role="navigation"><div class="container"><div class="navbar-header"><a class="navbar-brand" href="#">GetBookMarks</a></div><ul class="nav navbar-nav pull-right"><li>{{#link-to 'newstory'}}<span class="glyphicon glyphicon-plus"></span> Submit Story{{/link-to}}</li></ul></div></nav>

    注意上面我們用{{#link-to}}創(chuàng)建了一個(gè)指向路由的鏈接。請(qǐng)參閱文檔了解詳情。

    表單已經(jīng)有了,接下來(lái)要添加HTML 5本地存儲(chǔ)的功能。為了添加本地存儲(chǔ)支持,我們需要首先下載Ember Data和Local Storage Adapter JavaScript文件。將這些文件放在js/libs下。接著,在index.html中添加這些script標(biāo)簽。

    <script src="js/libs/jquery-1.9.1.js"></script> <script src="js/libs/handlebars-1.0.0.js"></script> <script src="js/libs/ember-1.1.2.js"></script> <script src="js/libs/ember-data.js"></script> <script src="js/libs/localstorage_adapter.js"></script> <script src="js/app.js"></script>

    如前所述,Ember Data是一個(gè)客戶端的ORM實(shí)現(xiàn),它使在底層存儲(chǔ)進(jìn)行CRUD操作很容易。這里我們將使用LSAdapter。在app.js中加入:

    App.ApplicationAdapter = DS.LSAdapter.extend({namespace: 'stories' });

    接著是定義model。一篇報(bào)道需要有url、title(標(biāo)題)、fullname(提交報(bào)道的用戶的全名)、excerpt(摘要),以及SubmittedOn(日期)信息。在下面的模型中,我們使用了字符串和日期類型。適配器默認(rèn)支持的屬性類型為字符串、數(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')});

    接著我們編寫(xiě)NewstoryController來(lái)持久化內(nèi)容:

    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在內(nèi)存中創(chuàng)建記錄。為了在localstorage中存儲(chǔ)記錄,我們需要調(diào)用Story對(duì)象的save方法。最后,我們將用戶重定向到index路由。

    接著我們測(cè)試下這個(gè)應(yīng)用,創(chuàng)建一個(gè)新的報(bào)道,接著打開(kāi)Chrome開(kāi)發(fā)者工具,在資源區(qū)域你可以查看這則報(bào)道。

    第六步 顯示所有報(bào)道

    接著我們要做的是,當(dāng)用戶訪問(wèn)首頁(yè)的時(shí)候,展示所有報(bào)道。

    正如我之前提到的,路由負(fù)責(zé)詢問(wèn)model。我們將加上IndexRoute,它會(huì)找出本地存儲(chǔ)中保存的所有報(bào)道。

    App.IndexRoute = Ember.Route.extend({model : function(){var stories = this.get('store').findAll('story');return stories;} });

    每個(gè)路由支持一個(gè)模板。IndexRoute支持index模板,因此我們需要修改index.html:

    <script type="text/x-handlebars" id="index"><div class="row"><div class="col-md-4"><table class='table'><thead><tr><th>Recent Stories</th></tr></thead>{{#each controller}}<tr><td>{{title}}</td></tr>{{/each}}</table></div><div class="col-md-8">{{outlet}}</div></div></script>

    現(xiàn)在訪問(wèn)/,我們會(huì)看到一個(gè)報(bào)道的列表:

    還有一個(gè)問(wèn)題,報(bào)道沒(méi)有按照時(shí)間順序排列。我們將創(chuàng)建一個(gè)IndexController負(fù)責(zé)排序。我們指定依照submittedOn屬性倒序排列,以確保新的報(bào)道出現(xiàn)在上面。

    App.IndexController = Ember.ArrayController.extend({sortProperties : ['submittedOn'],sortAscending : false });

    修改之后,我們會(huì)看到按照submittedOn屬性排序的報(bào)道。

    第七步 查看單獨(dú)的報(bào)道

    最后要實(shí)現(xiàn)的功能是:用戶點(diǎn)擊某則報(bào)道的時(shí)候會(huì)看到詳細(xì)信息。我們加一個(gè)路由:

    App.Router.map(function() {this.resource('index',{path : '/'},function(){this.resource('story', { path:'/stories/:story_id' });});this.resource('newstory' , {path : 'story/new'});});

    以上的代碼展示了如何嵌套路由。

    :story_id部分叫做動(dòng)態(tài)字段,因?yàn)橄鄳?yīng)的報(bào)道 id會(huì)被注入U(xiǎn)RL。

    然后我們添加根據(jù)報(bào)道id獲取報(bào)道的StoryRoute。

    App.StoryRoute = Ember.Route.extend({model : function(params){var store = this.get('store');return store.find('story',params.story_id);} });

    最后,我們更新下index.html,給每個(gè)報(bào)道添加鏈接:

    <script type="text/x-handlebars" id="index"><div class="row"><div class="col-md-4"><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 class="col-md-8">{{outlet}}</div></div></script><script type="text/x-handlebars" id="story"><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></script>

    修改完畢地后,可以在瀏覽器中直接看到結(jié)果。

    第八步 為submittedOn日期添加格式

    Ember下有輔助函數(shù)的概念。所有Handlebars模板都可以調(diào)用輔助函數(shù)。

    我們將使用moment.js庫(kù)為日期添加格式。將以下代碼加入index.html。

    <script src="http://cdnjs.cloudflare.com/ajax/libs/moment.js/2.4.0/moment.min.js"></script>

    接著我們將定義我們的第一個(gè)輔助函數(shù),該函數(shù)將日期轉(zhuǎn)為人類可讀的形式:

    Ember.Handlebars.helper('format-date', function(date){return moment(date).fromNow(); });

    最后我們?cè)趫?bào)道模板中加入format-data輔助函數(shù)。

    <script type="text/x-handlebars" id="story"><h1>{{title}}</h1><h2> by {{fullname}} <small class="muted">{{format-date submittedOn}}</small></h2>{{#each tagnames}}<span class="label label-primary">{{this}}</span>{{/each}}<hr><p class="lead">{{excerpt}}</p></script>

    報(bào)道頁(yè)面的效果如下:

    今天就到這里了。持續(xù)反饋。


    原文 Day 19: Ember--The Missing EmberJS Tutorial
    翻譯 SegmentFault

    總結(jié)

    以上是生活随笔為你收集整理的Day 19: EmberJS 入门指南的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。