<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                --- title: 編輯帖子 slug: editing-posts date: 0008/01/01 number: 8 points: 5 photoUrl: http://www.flickr.com/photos/ikewinski/9473337133/ photoAuthor: Mike Lewinski contents: 添加一個帖子編輯表單。|設置可編輯權限。|限制哪些屬性可以編輯。 paragraphs: 29 --- 上一章,我們已經學會了創建帖子,下面來學習編輯和刪除它們。頁面的代碼非常簡單,讓我們在這個時候來談論一下 Meteor 是如何管理用戶權限。 讓我們先設置我們的路由器,添加一個可以訪問帖子編輯頁的路徑,并設置它的數據上下文: ~~~js Router.configure({ layoutTemplate: 'layout', loadingTemplate: 'loading', notFoundTemplate: 'notFound', waitOn: function() { return Meteor.subscribe('posts'); } }); Router.route('/', {name: 'postsList'}); Router.route('/posts/:_id', { name: 'postPage', data: function() { return Posts.findOne(this.params._id); } }); Router.route('/posts/:_id/edit', { name: 'postEdit', data: function() { return Posts.findOne(this.params._id); } }); Router.route('/submit', {name: 'postSubmit'}); var requireLogin = function() { if (! Meteor.user()) { if (Meteor.loggingIn()) { this.render(this.loadingTemplate); } else { this.render('accessDenied'); } } else { this.next(); } } Router.onBeforeAction('dataNotFound', {only: 'postPage'}); Router.onBeforeAction(requireLogin, {only: 'postSubmit'}); ~~~ <%= caption "lib/router.js" %> <%= highlight "15~18" %> ### 帖子編輯模板 我們可以現在專注模板了。我們的 `postEdit` 模板就包含一個相當標準的表單: ~~~html <template name="postEdit"> <form class="main form"> <div class="form-group"> <label class="control-label" for="url">URL</label> <div class="controls"> <input name="url" id="url" type="text" value="{{url}}" placeholder="Your URL" class="form-control"/> </div> </div> <div class="form-group"> <label class="control-label" for="title">Title</label> <div class="controls"> <input name="title" id="title" type="text" value="{{title}}" placeholder="Name your post" class="form-control"/> </div> </div> <input type="submit" value="Submit" class="btn btn-primary submit"/> <hr/> <a class="btn btn-danger delete" href="#">Delete post</a> </form> </template> ~~~ <%= caption "client/templates/posts/post_edit.html" %> 用 `post_edit.js` 來配合這個的模板: ~~~js Template.postEdit.events({ 'submit form': function(e) { e.preventDefault(); var currentPostId = this._id; var postProperties = { url: $(e.target).find('[name=url]').val(), title: $(e.target).find('[name=title]').val() } Posts.update(currentPostId, {$set: postProperties}, function(error) { if (error) { // 向用戶顯示錯誤信息 alert(error.reason); } else { Router.go('postPage', {_id: currentPostId}); } }); }, 'click .delete': function(e) { e.preventDefault(); if (confirm("Delete this post?")) { var currentPostId = this._id; Posts.remove(currentPostId); Router.go('postsList'); } } }); ~~~ <%= caption "client/templates/posts/post_edit.js" %> 相信你現在已經對這些代碼都相當的熟悉了。 我們有兩個事件回調函數:一個用于表單的 `submit` 事件,一個用于刪除鏈接的 `click` 事件。 刪除鏈接的回調函數是非常簡單的:先防止默認點擊事件,然后提示確認窗口。如果確認刪除,它將從模板的數據上下文中獲得當前帖子的 ID ,然后刪除它,最后把用戶重定向到主頁。 更新的回調函數需要長一點時間,但并不復雜。在防止默認提交事件然后獲取了當前帖子之后,我們將從表單中獲取相關字段的值,并將它們存儲在一個 `postProperties` 的對象中。 然后,我們把該對象通過 [`$set`](http://docs.mongodb.org/manual/reference/operator/update/set/) 操作符(只更新指定字段的值,保留其他字段的值)傳遞給 Meteor 的 `Collection.update()` 方法,并通過回調函數去判斷如果更新失敗就顯示錯誤信息;如果更新成功了,將自動返回到該帖子的頁面。 ### 添加鏈接 我們還應該添加一個編輯帖子的鏈接,以便用戶可以訪問到帖子編輯頁面: ~~~html <template name="postItem"> <div class="post"> <div class="post-content"> <h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3> <p> submitted by {{author}} {{#if ownPost}}<a href="{{pathFor 'postEdit'}}">Edit</a>{{/if}} </p> </div> <a href="{{pathFor 'postPage'}}" class="discuss btn btn-default">Discuss</a> </div> </template> ~~~ <%= caption "client/templates/posts/post_item.html" %> <%= highlight "5~8" %> 當然,我們不能讓你的帖子提供給其他用戶去編輯。這就要通過 `ownPost` helper 來幫忙: ~~~js Template.postItem.helpers({ ownPost: function() { return this.userId === Meteor.userId(); }, domain: function() { var a = document.createElement('a'); a.href = this.url; return a.hostname; } }); ~~~ <%= caption "client/templates/posts/post_item.js" %> <%= highlight "2~4" %> <%= screenshot "8-1", "帖子編輯表單。" %> <%= commit "8-1", "添加帖子編輯表單。" %> 我們的帖子編輯表單看起來很好,但是目前還不能夠進行任何的編輯,這是為什么? ### 設置權限 自從我們移除了 `insecure` 包,現在所有客戶端的修改都會被拒絕。 為了解決這個問題,我們需要建立一些權限規則。首先,在 `lib` 目錄下創建一個新的 `permissions.js` 文件。這樣做將會首先加載我們權限文件(它在服務端和客戶端都可以被加載到): ~~~js // check that the userId specified owns the documents ownsDocument = function(userId, doc) { return doc && doc.userId === userId; } ~~~ <%= caption "lib/permissions.js" %> 在[創建帖子](/chapter/creating-posts)這個章節,我們拋棄了 `allow()` 方法,因為我們只通過服務端方法去插入新的帖子(繞過了 `allow()` 方法)。 但是現在我們要在客戶端編輯和刪除帖子!我們回到 `posts.js` 文件并添加 `allow()` : ~~~js Posts = new Mongo.Collection('posts'); Posts.allow({ update: function(userId, post) { return ownsDocument(userId, post); }, remove: function(userId, post) { return ownsDocument(userId, post); } }); //... ~~~ <%= caption "lib/collections/posts.js" %> <%= highlight "3~6" %> <%= commit "8-2", "添加基本權限來檢查帖子的擁有者。" %> ### 限制編輯 盡管你可以編輯自己的帖子,但并不意味著你可以允許去編輯帖子的**每個**屬性。例如,我們不允許用戶創建一個帖子之后,再將其分配給其他用戶。 我們用 Meteor 的 `deny()` 方法,以確保用戶只能編輯特定的字段: ~~~js Posts = new Mongo.Collection('posts'); Posts.allow({ update: function(userId, post) { return ownsDocument(userId, post); }, remove: function(userId, post) { return ownsDocument(userId, post); } }); Posts.deny({ update: function(userId, post, fieldNames) { // 只能更改如下兩個字段: return (_.without(fieldNames, 'url', 'title').length > 0); } }); //... ~~~ <%= caption "lib/collections/posts.js" %> <%= highlight "8~13" %> <%= commit "8-3", "只允許更改帖子的某些屬性。" %> 代碼中的 `fieldNames` 數組,它包含了需要被修改的字段,并使用 [Underscore](http://underscorejs.org/) 的 `without()` 方法返回一個*不包含* `url` 和 `title` 字段的子數組。 正常情況下,這個數組應該是空的,它的長度應該是0。如果有人采取其他操作,這個數組的長度將變為1或更多,回調函數將返回 `true` (因此禁止更新)。 你也許注意到了在我們的代碼中沒有檢查鏈接是否重復的代碼。這就意味著用戶成功添加一個鏈接后,再編輯時就會繞過檢查。這個問題同樣可以通過為編輯帖子表單使用 Meteor 內置方法來解決,但是我們將它作為練習留給讀者。 <% note do %> ### 內置方法的回調 vs 客戶端數據操作 創建帖子,我們使用的是 `postInsert` 的內置方法,而編輯和刪除帖子,我們直接在客戶端調用 `update` 和 `remove`,并通過 `allow` 和 `deny` 去限制使用權限。 我們該如何去選擇使用呢? 當操作相對比較直觀,你可以通過 `allow` 和 `deny` 去設置你的規則的時候,直接在客戶端進行操作通常會更簡單。 然而,一旦你需要做一些在用戶控制以外的事情(比如設置一個新帖子的時間戳,或者把帖子分配到正確的用戶),這種情況使用內置方法會更好。 內置方法也適用在其他的一些情景: - 當你需要通過內置方法的回調函數去獲得返回值的時候,而不是等待響應和同步才傳遞的數據。 - 對于一些繁重的數據庫操作,比如要提取大量的數據集合。 - 計算或者合計數據的時候(比如:計數、平均值、求和)。 [請閱讀我們的 blog](https://www.discovermeteor.com/blog/meteor-methods-client-side-operations/) 來深入了解這個話題。 <% end %>
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看