2017-04-02 5 views
0

BlazeテンプレートとフロールータでMeteorを使用すると、新しい要素を作成するとページが更新されず、同じ要素が削除されるとすぐに消滅します。ここでは、テンプレートのコードは次のとおりです。Meteorテンプレートの更新が不一致

<template name="EditProject"> 
    ... 
    {{#each currentCounts }} 
     <div class="count-box">{{> CountDelete }}</div> 
    {{/each}} 
    ... 
    <btn class="btn waves-effect waves-light h-button" id="add-count">Add Count</btn> 
    ... 
</template> 

<template name="CountDelete"> 
    <div class="card blue-grey lighten-2 count-box"> 
     <div class="card-content white-text"> 
      <span class="card-title"> 
       {{ name }} 
      </span> 
      {{ notes }} 
     </div> 
     <div class="card-action"> 
      <btn class="btn waves-effect waves-light delete-count"> 
       <i class="mdi mdi-delete"></i> 
      </btn> 
      <a class="btn waves-effect waves-light" href="/edit_count/{{ _id }}"> 
       <i class="mdi mdi-pencil"></i> 
      </a> 
     </div> 
    </div> 
</template> 

currentCountsのソースはこれです:

Template.EditProject.helpers({ 
    currentCounts: function() { 
     var projectId = FlowRouter.getParam('projectId'); 
     const project = Projects.findOne(projectId); 
     var counts = Counts.find({ 
      _id: { $in: project.counts } 
      }, 
      { 
       sort: { sort_order: -1 } 
      } 
     ); 
     return counts; 
    } 
}) 

述べたように、.delete-countボタンが関連付けられたカウントを削除してもUIはそれが持っていることを示すために更新しますクリック行った。カウントを追加すると(クリックして#add-count)カウントが正しく作成されますが、ページは更新されません。簡単なフリッカーがありますが、それだけです。ページをリフレッシュすると、新しいカウントが表示されます。誰でも何が起こっているのかを提案できますか?

編集:コメントに要求されるようにここでは、サブスクリプションです:

Template.EditProject.onCreated(function() { 
    var self = this; 
    self.autorun(function() { 
     var projectId = FlowRouter.getParam('projectId'); 
     self.subscribe('single-project',projectId); 
     self.subscribe('project-counts',projectId); 
    }) 
}) 

さらに編集:

最初にこのルートにアクセスすると、それは、経由して複数のカウントのリストを示す必要があるとして、ページのレンダリング{{#each currentCounts}}。これらのカウントの1つを削除すると、画面から即座に消えますが、新しいものを追加すると、ページを更新するまで表示されません。

別の編集:要求されたように(サーバ/ main.js内)

リスナーとサーバ公開コードを追加しました。奇妙なことに、アプリケーションを再起動すると、すべてが正常に動作するようになりましたが、数分で私が説明したのと同じ振る舞いが再確認されました。

Meteor.publish('project-counts', function projectPublication(projectId) { 
    let project = Projects.findOne({_id: projectId, knitter: this.userId}); 
    return Counts.find({_id: { $in: project.counts }}); 
}); 
Meteor.publish('single-project', function projectPublication(projectId) { 
    return Projects.find({_id: projectId, knitter: this.userId}); 
}); 

'click #add-count'(event) { 
    //TODO: Check for duplicate count name 
    var projectId = FlowRouter.getParam('projectId'); 
    var countName = $('#new-count').val(); 
    var countNotes = $('#new-count-notes').val(); 

    if (!countName) { 
     $("#errors-go-here").empty(); 
     Blaze.renderWithData(Template.EditProjectErrors, { 
      errors: ['You must supply a name for the new count.'] 
     }, $("#errors-go-here")[0]) 
     $('.modal').modal(); 
     $('#validation-errors').modal('open'); 
     return; 
    } 

Template.EditProject.events({ 
    ... 
    Meteor.call('projects.add-count',projectId,countName,countNotes, function(error) { 
      if (error) { 
       console.log("Count add error: " + error); 
       Materialize.toast('Failed to add count \'' + countName + '\'!', 3000, 'orange darken-4'); 
       return false; 
      } else { 
       Materialize.toast('Count \'' + countName + '\' added!', 3000, 'blue-grey'); 
       $('#new-count').val(null); 
       $('#new-count-notes').val(null); 
       // Running this makes the missing count show up, but this is clearly not the right way to do it... 
       //location.reload(); 
      } 
     }); 
    }, 
    ... 
)} 



Template.CountDelete.events({ 
    'click .delete-count'(event) { 
     var self = this; 
     var projectId = FlowRouter.getParam('projectId'); 
     var countId = self._id; 
     const count = Counts.findOne(countId); 
     const name = count.name; 

     Meteor.call('projects.delete-count',projectId,countId, function(error) { 
      if (error) { 
       console.log("Count add error: " + error); 
       Materialize.toast('Failed to delete count \'' + name + '\'!', 3000, 'orange darken-4'); 
       return false; 
      } else { 
       Materialize.toast('Count \'' + count.name + '\' deleted!', 3000, 'blue-grey'); 
      } 
     }); 

    }, 

}) 

詳細情報:ページが読み込まれると、正常に動作することがわかりました。しかし、それが再ロードされた場合、それは誤動作を開始します。だから、私は当初、コードが変更されたためにMeteorがページを更新したときに正しい動作が起こっていることに気付かなかったでしょう。

+0

ここであなたはcountsコレクションを購読しましたか?それはeditprojectテンプレートのルートのonWait関数かテンプレートのonCreatedですか? –

+0

投稿を更新して、カウント(およびプロジェクト)の購読場所を表示しました。 – knirirr

+0

私が理解しているところから、あなたはプロジェクトコレクションから1つのレコードを取得しています。そして、そのプロジェクトIDでCountsコレクションを検索しています。そして、カウントコレクションがあなたが購読しているプロジェクトカウントと同じであることを願っています。 Countsコレクションでは、_id = project.id –

答えて

1

完全にするには、メソッドコード(つまり、'projects.add-count''projects.delete-count')も共有しているはずです。

つまり、私は彼らが projectIdProjectsコレクションに等しいとcounts文書の配列フィールドを更新すると思われる。

この場合、'project-counts'の出版物を見ると、それはProjects.findOneというクエリに依存していることがわかります。このクエリは、標準のMeteorでサーバー側で反応しません。

は、したがって、あなたが「カウント」を追加したときに起こることは、新たな文書がCountsコレクションに追加されていることであり、その_idは非常におそらく正しく、プロジェクトのcountsフィールドに記録されているが、これはパブリケーションのコードを再実行しません。したがって、カーソルセレクタクエリは変更されず、クライアントはCountsコレクションに変更を受け取りません。

メソッドコードがクライアントとサーバーの両方にロードされていると仮定すると、クライアントはスタブ/シミュレーションを実行してこの新しいドキュメントを挿入し、プロジェクトのcountsをローカル更新してUIを更新します。

しかし、サーバーでもメソッドが実行されるため、パブリケーションが変更されないため、Countsの新しいドキュメントはクライアントに送信されず、クライアントには表示されなくなります。これはあなたが観察するちらつきを作ります。あなたはCountsからに文書を削除とき

今、私たちは特に、あなたも出版クエリかかわらず、あなたのUIが正しく削除を反映している理由です、そして出版カーソルを更新Countsコレクションから、それを削除すると仮定することができますセレクターは変更されませんでした。最後に

、ページをリフレッシュとき、パブリケーションのコードは完全に、したがって、あなたの新しいカーソルが今、新たが含まれ、正しいクエリセレクタにつながるProjectsコレクション、中にあなたの文書の最新バージョンを使用して、再評価されますCountsに文書を追加しました。

問題を解決するには、リアクティブな結合を使用するか、複合パッケージを公開するようにしてください。

など。 https://stackoverflow.com/a/32920733/5108796Meteor.publish: publish collection which depends on other collection

+0

非常に便利な説明をありがとう。あなたは 'add-count'と' delete-count'メソッドの機能について本当に正しいです、そして、あなたは関連するサブスクリプションをリンクしアップデートするパッケージを追加することによって問題が解決されたことがわかりました。 – knirirr