4

私は meteor を初めて使用するので、これらの関数がどのように機能するか、およびどのように使用する必要があるかについての非常に基本的な説明を受け取りたいと思っています。そうでなければ、私が達成したいことにより適した方法があれば、その知識をいただければ幸いです。

私が達成したいと思っていた機能:

特定のユーザーに割り当てられたドキュメント内に数値を含む Mongo コレクションがあります。

ドキュメントから取得した値を使用して width: xx% を「プログレスバー」の css インライン スタイルに設定します。しかし、私が持っている他の用途は、この値が変更されるたびに実行されるある種の「リアクティブ」関数を実行することです。これにより、プログレスバーの現在の値に基づいて、このプログレスバーの背景色を動的に更新できます。低い場合は「赤」、高い場合は「緑」と考えてください。

project.html:

<template name="progressBar">
  <div id="progress-bar" style="width:{{curValue}}; background-color:*dynamicColor*;"></div>
</template>

project.js:

Progress = new Mongo.Collection("progress");

Template.progressBar.helpers({
  curValue: function () {
    return Progress.findOne({user: Meteor.userId()}).curValue;
  }
});

上記は時々動作します。しかし、それは信頼できるものではないようで、現在私にとっては機能していません. undefined のプロパティ 'curValue' を読み取れないというエラーが表示されます。オンラインで調査したところ、コレクションが読み込まれる前にこのドキュメントにアクセスしようとしています。しかし、私は本当に直接的な解決策を見つけることができず、そのエラーを回避するためにこれをどのように構築するべきかについて頭を悩ませています。

次の問題は、その値の変化を観察し、変化した場合は背景色を変更する関数を実行することです。

以下は、私が動作させようとした自動実行/監視コードのいくつかのタイプです。

Session.set('currentValue', Progress.findOne({user:Meteor.userId()}).curValue);
Tracker.autorun(function(){
  var currentValue = Session.get('currentValue');
  updateColor(currentValue);
});

var currentValue = Progress.findOne({user:Meteor.userId()}).curValue);
var handle = currentValue.observeChanges({
  changed: function (id, currentValue) {
    updateColor(currentValue);
  }
});

質問/問題を要約するには:

いくつかのインライン css で mongo db ドキュメントの値を使用し、その値の変更も追跡したいと考えています。値が変更されたら、div の背景色を更新する関数を実行したいと考えています。


アップデート

以下の@Ethaanの回答を使用して、コレクションデータのサブスクリプション/テンプレートの使用を修正できました。もう少し掘り下げて、パブリッシュ/サブスクライブ メソッドをより深く理解し、サブスクリプションでコールバックを適切に使用して、コレクションが読み込まれた後の適切なタイミングで Tracker.autorun 関数を実行する方法を学びました。以下の回答を拡張して、ドキュメントの値に基づいて色を更新する関数を実行するリアクティブな Tracker.autorun を含めることができました。

最終的に動作するようになったコードは次のとおりです。

project.js

if (Meteor.isClient) {

  Progress = new Mongo.Collection("progress");

  Template.content.onCreated(function () {
    var self = this;

    self.autorun(function () {
      self.subscribe("progress", function(){
        Tracker.autorun(function(){
          var query = Progress.findOne({user: Meteor.userId()}).level;
          changeColor(query);
        });
      });
    });
  });

  Template.content.helpers({
    value: function(){
      return Progress.findOne({user: Meteor.userId()}).level;
    }
  });

  function changeColor(value){
    //run some code
  }

}

if (Meteor.isServer) {

  Progress = new Mongo.Collection("progress");

  Meteor.publish("progress", function () {
    return Progress.find({user: this.userId});
  });

}

project.html

<head>
  <title>Project</title>
</head>

<body>
  {{> standard}}
</body>

<template name="standard">
  ...
  {{> content}}
</template>

<template name="content">
  {{#if Template.subscriptionsReady}}
      {{value}}
    {{else}}
       0
   {{/if}}
</template>
4

1 に答える 1

6

つまり、コレクションが読み込まれる前にこのドキュメントにアクセスしようとしています

問題が発生したようです。次は、いくつかの可能な解決策に乗りましょう。

メテオ バージョン 1.1

新しい流星バージョン 1.1を使用している場合(実行中を確認できますmeteor --version)

これを使って。

最初にonCreated関数でこれを使用します。

Template.progressBar.onCreated(function () {
  var self = this;

  self.autorun(function () {
    self.subscribe("Progress");
  });
});

DOCS でsubscriptionReadyの詳細を参照してください。HTMLでは次のように使用します。

<template name="progress">
  {{#if Template.subscriptionsReady}}
      <div id="progress-bar" style="width:{{curValue}}; background-color:*dynamicColor*;"></div>
    {{else}}
       {{> spinner}} <!-- or whatever you have to put on the loading -->
   {{/if}}
</template>

1.0.4未満のメテオ

ルーターに次のようなものを持つことができますwaitOn:function(){}

waitOn:function(){
  Meteor.subscribe("Progress");
}

または、ヘルパーが非同期であるため、このようなことを行います (推奨されません)。

Template.progressBar.helpers({
  curValue: function () {
    query = Progress.findOne({user: Meteor.userId()}).curValue;
    if(query != undefined){
      return query;
    }else{
     console.log("collection isn't ready")
    }
  }
});
于 2015-04-04T06:44:30.330 に答える