流星:Tracker.autorun / observeChanges&集合未按预期工作 [英] Meteor: Tracker.autorun / observeChanges & collections not working as expected

查看:325
本文介绍了流星:Tracker.autorun / observeChanges&集合未按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新的使用meteor,所以我希望收到一个非常基本的解释这些功能如何工作,以及我应该如何使用它们。否则,如果有一个更适合我希望实现的方法,知识将被欣赏。



我希望实现的功能: / p>

我有一个Mongo集合,其中包含分配给特定用户的文档中的数字值。



使用我从文档中获取的值填充宽度:xx%在一些css在线样式在'progressbar'。但另一个使用我有它的是执行某种反应功能运行时,只要这个值改变,可以基于进度条的当前值动态更新这个进度条的背景颜色。认为红色为低和绿色为高:



project.html:



< < template name =progressBar>
< div id =progress-barstyle =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;
}
});

上面有时会工作。但它似乎不可靠,现在不为我工作。我得到的错误,无法读取属性'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){
//运行一些代码
}

}

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>


解决方案


我尝试在
集合加载之前访问此文档


似乎你遇到了问题,一些可能的解决方案。



Meteor 1.1版



meteor (您可以检查运行 meteor --version





首先在 onCreated 函数上使用

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

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

查看更多关于 subscriptionReady
现在在 HTML 上使用这样。

 < template name =progress > 
{{#if Template.subscriptionsReady}}
< div id =progress-barstyle =width:{{curValue}}; background-color:* dynamicColor *;> ; / div>
{{else}}
{{> spinner}}<! - 或任何你必须加载 - >
{{/ if}}
< / template>

1.0.4下的Meteor



你可以在路由器上像一个 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 is not ready)
}
}
});


I am new to using meteor, so I am hoping to receive a very basic explanation of how these functions work, and how I am supposed to be using them. Otherwise, if there is a method that would be better suited to what I am hoping to achieve, the knowledge would be appreciated.

The functionality I was hoping to achieve:

I have a Mongo collection that contains a number value within documents that are assigned to specific users.

I will use the value that I get from the document to populate a width: xx% in some css in-line styling on a 'progressbar'. But the other use I have for it is performing some kind of 'reactive' function that runs whenever this value changes which can update the background color of this progress bar dynamically based off of the current value of the progressbar. Think 'red' for low and 'green' for high:

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;
  }
});

The above sometimes works. But it doesn't seem to be reliable and isn't working for me right now. I get errors about cannot read property 'curValue' of undefined. From what I have researched online, that means that I am trying to access this document before the collection has loaded. But I really cannot find a direct solution or wrap my head around how I am supposed to be structuring this to avoid that error.

The next problem is observing changes to that value and running a function to change the background color if it does change.

Here are a few of the types of autorun/observe pieces of code I have tried to make work:

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);
  }
});

To sum up the question/problem:

I want to use a value from a mongo db document in some in-line css, and also track changes on that value. When the value changes, I want a function to run that will update the background color of a div.


Update

Using @Ethaan 's answer below, I was able to correct my subscription/template usage of my collection data. I did a bit more digging and come to a greater understanding of the publish/subscribe methods and learned how to properly use the callbacks on subscriptions to run my Tracker.autorun function at the appropriate time after my collection had loaded. I was able to expand on the answer given to me below to include a reactive Tracker.autorun that will run a function for me to update my color based on my document value.

The code that I ultimately got working is as follows:

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>

解决方案

that means that I am trying to access this document before the collection has loaded

Seems like you get the problem, now lets get ride to some possible solutions.

Meteor version 1.1

If you are using the new meteor version 1.1 (you can check running meteor --version)

use this.

First on the onCreated function use this.

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

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

See more about subscriptionReady on the DOCS. Now on the HTML use like this.

<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>

Meteor under 1.0.4

You can have on the router something like a waitOn:function(){}

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

or since helper are asynchronous do something like this (not recommendable).

Template.progressBar.helpers({
  curValue: function () {
    query = Progress.findOne({user: Meteor.userId()}).curValue;
    if(query != undefined){
      return query;
    }else{
     console.log("collection isn't ready")
    }
  }
});

这篇关于流星:Tracker.autorun / observeChanges&amp;集合未按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆