文章來源:http://blog.ddlisting.com/2016/04/16/fa-bu-xiang-mu-jia-ru-crudgong-neng/css
接着前面三篇:html
發佈方式一git
發佈的詳細教程請看guide on firebase。執行以下命令發佈項目。github
npm install -g firebase-tools ember build --prod firebase login firebase init
執行命令過程須要輸入一個public的目錄,輸入dist
後按enter
。更新firebase.json
的內容。web
{ "firebase": "YOUR-APP-NAME", "public": "dist", "rewrites": [{ "source": "**", "destination": "/index.html" }] }
遺憾的是在我電腦上一直提示沒有firebase
命令,即便我已經安裝了這個插件也不行。數據庫
發佈方式二npm
因爲上述方式沒法發佈想到到firebase,因此使用最原始的發佈方式,使用ember
命令打包項目。而後本身把項目部署到服務器上。json
ember build --prod
,等到命令執行完畢後再項目的dist
目錄下的全部文件即便打包後的項目文件。webapps
目錄下。修改項目的library列表頁面,增長刪除和修改功能。bootstrap
<!-- app/templates/libraries/index.hbs --> <h2>List</h2> <div class="row"> {{#each model as |library|}} <div class="col-md-4"> <div class="panel panel-default library-item"> <div class="panel-heading"> <h3 class="panel-title">{{library.name}}</h3> </div> <div class="panel-body"> <p>Address: {{library.address}}</p> <p>Phone: {{library.phone}}</p> </div> <div class="panel-footer text-right"> {{#link-to 'libraries.edit' library.id class='btn btn-success btn-xs'}}Edit{{/link-to}} <button class="btn btn-danger btn-xs" {{action 'deleteLibrary' library}}>Delete</button> </div> </div> </div> {{/each}} </div>
相比原來的代碼增長了一個鏈接和一個按鈕,分別用於編輯和刪除library信息。相對於須要增長一個路由libraries/edit
和一個處理的動做{{action 'deleteLibrary'}}
。 若是此時運行http://localhost:4200/libraries會出現錯誤,由於還沒定義路由libraries/edit
和action
。別急,先一步步來,下面先增長一些css樣式。ubuntu
# app/styles/app.scss @import 'bootstrap'; body { padding-top: 20px; } html { overflow-y: scroll; } .library-item { min-height: 150px; }
libraries/edit
和路由對應的模板簡單起見直接使用Ember CLI命令建立,就不手動建立了。執行命令:ember g route libraries/edit
建立路由和路由對應的模板。 建立完成以後還須要手動修改app/router.js
文件,內容以下:
// app/router.js import Ember from 'ember'; import config from './config/environment'; var Router = Ember.Router.extend({ location: config.locationType }); Router.map(function() { this.route('about'); this.route('contact'); this.route('admin', function() { this.route('invitation'); this.route('contact'); }); this.route('libraries', function() { this.route('new'); // :library_id是一個動態段,會根據實際的URL變化 this.route('edit', { path: '/:library_id/edit' }); }); }); export default Router;
注意this.route('edit', { path: '/:library_id/edit' });
這行代碼的設置。與普通的路由稍有不一樣這裏增長了一個參數,而且參數內使用path
設定路由渲染以後edit
會被/:library_id/edit
替換。 編譯、渲染以後的URL格式爲http://example.com/libraries/1234/edit
其中:library_id
這是一個動態段,這個URL例子中動態段library_id
的值就是1234
,而且能夠在路由類中獲取這個動態段的值。 更多有關動態段的介紹請看Ember.js 入門指南之十三{{link-to}} 助手或者Dynamic Segments。
配置完路由以後修改路由libraries/edit.js
的代碼。
// app/routes/libraries/edit.js import Ember from 'ember'; export default Ember.Route.extend({ model(params) { // 獲取動態段library_id的值 return this.store.findRecord('library', params.library_id); }, actions: { saveLibrary(newLibrary) { newLibrary.save().then(() => this.transitionTo('libraries')); }, willTransition(transition) { let model = this.controller.get('model'); if (model.get('hasDirtyAttributes')) { let confirmation = confirm("Your changes haven't saved yet. Would you like to leave this form?"); if (confirmation) { model.rollbackAttributes(); } else { transition.abort(); } } } } });
代碼this.store.findRecord('library', params.library_id);
的意思是根據模型的id
屬性值查詢某個記錄,其中library_id
就是動態段的值,這個值是Ember解析URL獲得的。正如前面所說:http://example.com/libraries/1234/edit
這個URL動態段的值就是1234
。 Ember會自動根據URL的格式解析獲得。而且能夠在路由類中獲取。默認狀況下動態段的值是數據的id
值。代碼中的另外兩個方法saveLibrary()
和willTransition()
在前一篇文章模型,保存數據到數據庫已經介紹過,在此再也不贅述。 方法willTransition()
的做用就是:當用戶修改了數據以後沒有點擊保存就離開頁面時會提示用戶是否確認不保存就離開頁面!經過控制器中的屬性hasDirtyAttributes
判斷頁面的值是否發生了變化。方法rollbackAttributes()
會重置model
中的值。方法abourt()
能夠阻止路由的跳轉,有關路由的跳轉請看Ember.js 入門指南之二十四終止與重試路由跳轉。從new.hbs
複製代碼到edit.hbs
,而後在稍加修改。
<!-- app/templates/libraries/edit.hbs --> <h2>Edit Library</h2> <div class="form-horizontal"> <div class="form-group"> <label class="col-sm-2 control-label">Name</label> <div class="col-sm-10"> {{input type="text" value=model.name class="form-control" placeholder="The name of the Library"}} </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">Address</label> <div class="col-sm-10"> {{input type="text" value=model.address class="form-control" placeholder="The address of the Library"}} </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">Phone</label> <div class="col-sm-10"> {{input type="text" value=model.phone class="form-control" placeholder="The phone number of the Library"}} </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-default" {{action 'saveLibrary' model}}>Save changes</button> </div> </div> </div>
等待項目重啓完成,進入到修改界面,任意修改界面上的數據,不點擊保存而後任意點擊其餘連接會彈出提示,詢問你是否確認離開頁面。操做步驟以下截圖。
注意:看瀏覽器的URL。首頁模板代碼{{#link-to 'libraries.edit' library.id class='btn btn-success btn-xs'}}Edit{{/link-to}}
中的路由libraries.edit
渲染以後會獲得形如libraries/xxx/edit
的URL,其中xxx
就是動態段的值。
彈出提示信息。若是點擊取消會停留在當前頁面,若是選中肯定會跳轉到首頁(由於我點擊的是菜單的Home)。
成功保存了修改的內容。到此實現了修改功能。
刪除功能比修改更加簡單,直接在方法deleteLibrary
里根據id
屬性值刪除數據便可。id
屬性值已經在模板頁面做爲參數傳遞到方法中。直接獲取便可。
// app/routes/libraries/index.js import Ember from 'ember'; export default Ember.Route.extend({ model() { return this.store.findAll('library'); }, actions: { // 刪除一個library記錄 deleteLibrary(library) { //參數library已經在模板中傳遞過來 let confirmation = confirm('Are you sure?'); if (confirmation) { library.destroyRecord(); } } } });
模板中是這樣調用刪除方法的<button class="btn btn-danger btn-xs" {{action 'deleteLibrary' library}}>Delete</button>
,看到參數library
了吧,這個參數就是一個library
模型對象。 能夠直接調用方法destroyRecord()
實現刪除數據。
選中肯定以後刪除就會馬上刪除,列表上的數據也會動態更新。
參照library的功能實現contact的刪除與修改。
ember g route admin/contact/edit ember g template admin/contact/index
// app/router.js this.route('admin', function() { this.route('invitation'); this.route('contact', function() { this.route('edit', { path: '/:contact_id/edit' }); }); });
省略其餘內容,僅僅列出修改部分。
admin/contact.hbs
的內容到admin/contact/index.hbs
,而後空admin/contact.hbs
再在文件內添加{{outlet}}
admin/contact.hbs
<!-- app/templates/admin/contact.hbs --> {{outlet}}
admin/contact/index.hbs
{{! app/templates/admin/contact/index.hbs}} <h1>Contacts</h1> <table class="table table-bordered table-striped"> <thead> <tr> <th>ID</th> <th>E-mail</th> <th>Message</th> <th>Operation</th> </tr> </thead> <tbody> {{#each model as |contact|}} <tr> <th>{{contact.id}}</th> <td>{{contact.email}}</td> <td>{{contact.message}}</td> <td> {{#link-to 'admin.contact.edit' contact.id class='btn btn-success btn-xs'}}Edit{{/link-to}} <button class="btn btn-danger btn-xs" {{action 'deleteContact' contact}}>Delete</button> </td> </tr> {{/each}} </tbody> </table>
增長刪除、修改按鈕。
app/templates/contact.hbs
到admin/contact/edit.hbs
並作修改admin/contact/edit.hbs
{{! app/templates/admin/contact/edit.hbs}} <div class="col-md-6 col-xs-6"> <form> <div class="form-group"> <label for="exampleInputEmail1">Email address</label> {{input type="email" value=model.email class="form-control col-sm-6 col--6" placeholder="Please type your e-mail address." autofocus="autofocus"}} </div> <div class="form-group"> <label for="exampleInputPassword1">Your message</label> {{textarea class="form-control" placeholder="Your message. (At least 5 characters.)" rows="7" value=model.message}} </div> <button class="btn btn-primary" disabled={{model.isDisabled}} {{action 'saveContact' model}}>Save</button> {{#link-to 'admin.contact' class="btn btn-default"}}Return{{/link-to}} </form> </div>
routes/context.js
// app/routes/contact.js import Ember from 'ember'; export default Ember.Route.extend({ model: function() { return this.store.findAll('contact'); }, actions: { deleteContact: function(contact) { let confirmation = confirm('Are you sure?'); if (confirmation) { contact.destroyRecord(); } } } });
app/routes/admin/contact/edit.js
// app/routes/admin/contact/edit.js import Ember from 'ember'; export default Ember.Route.extend({ model(params) { // 獲取動態段library_id的值 return this.store.findRecord('contact', params.contact_id); }, actions: { saveContact(newContact) { newContact.save().then(() => this.transitionTo('admin.contact')); }, willTransition(transition) { let model = this.controller.get('model'); if (model.get('hasDirtyAttributes')) { let confirmation = confirm("Your changes haven't saved yet. Would you like to leave this form?"); if (confirmation) { model.rollbackAttributes(); } else { transition.abort(); } } } } });
運行結果再也不截圖列出,請讀者自行試驗。
<br> 爲了照顧懶人我把完整的代碼放在[GitHub](https://github.com/ubuntuvim/library-app)上,能夠拿來作參照。博文通過屢次修改,博文上的代碼與github代碼可能有出入,不過影響不大!若是你以爲博文對你有點用,請在github項目上給我點個`star`吧。您的確定對我來講是最大的動力!!