admin管理员组文章数量:1336631
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 e 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>
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 e 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>
Share
Improve this question
edited Apr 4, 2015 at 9:10
Dreverz
asked Apr 4, 2015 at 6:36
DreverzDreverz
431 silver badge4 bronze badges
1
- help me understand why you wired it up the way you did. why have the template level subscribe in the autorun when you're only going to be calling the subscription once (because you're not passing in a reactive variable to the subscription)? Why a autorun within a autorun, for example why not return this.ready() from the publication and then make your call to change color? – Aaron Commented Jun 17, 2015 at 18:09
1 Answer
Reset to default 6that 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 remendable).
Template.progressBar.helpers({
curValue: function () {
query = Progress.findOne({user: Meteor.userId()}).curValue;
if(query != undefined){
return query;
}else{
console.log("collection isn't ready")
}
}
});
本文标签: javascriptMeteor TrackerautorunobserveChanges amp collections not working as expectedStack Overflow
版权声明:本文标题:javascript - Meteor: Tracker.autorunobserveChanges & collections not working as expected - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742380120a2463935.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论