May 10, 2021 Meteor
If collections are the core functionality of Meteor, responsiveness can make this core more powerful.
Collections fundamentally change the way your application's data is processed. This way, instead of manually checking for data changes (for example, through an AJAX call) and modifying HTML pages based on those changes, Meteor can detect changes to the data at any time and apply them seamlessly to your user interface.
Let's think about it: In the background, when the underlying data collection is updated, Meteor is able to modify any part of the user interface right away.
This real-time approach is to trigger a callback when the pointer to the data changes by using
.observe()
W
e can use these callbacks to change the DOM (HTML rendered by our web page).
Code like this:
Posts.find().observe({
added: function(post) {
// when 'added' callback fires, add HTML element
$('ul').append('<li id="' + post._id + '">' + post.title + '</li>');
},
changed: function(post) {
// when 'changed' callback fires, modify HTML element's text
$('ul li#' + post._id).text(post.title);
},
removed: function(post) {
// when 'removed' callback fires, remove HTML element
$('ul li#' + post._id).remove();
}
});
You probably already know how this code handles complex things quickly. I
magine if we were to modify any of the
properties of a
post, it would be accompanied by
<li>
in the post's hashtag on the page.
As we begin to rely on more data information, we can even do more complex processing, which can be done in real time.
Using the above patterns is sometimes necessary, especially when working with third-party widgets. For example, suppose we want to add or remove locations on the map in real time based on collection data (that is, to show the location of the currently logged-in user).
In this case, in order for the map to "talk" to Meteor's collection, you need
observe()
callback method to handle data changes.
For example, you need
added
removed
to
dropPin()
removePin()
API.
Meteor gives us a better approach: a declared approach, the core of which is responsive. This declaration allows us to define the relationships between objects and keep them in sync, so that we don't have to specify the appropriate behavior for each possible modification.
This is a powerful concept because there are many real-time inputs that can occur in our unpredictable time. Declare the way we render HTML based on responsive data, so meteor can monitor that data and bind the user interface directly to the data.
Overall, to replace
observe
callback, Meteor can let us write these:
<template name="postsList">
<ul>
{{#each posts}}
<li>{{title}}</li>
{{/each}}
</ul>
</template>
Then get our list of posts:
Template.postsList.helpers({
posts: function() {
return Posts.find();
}
});
In the background, Meteor actually
observe()
callback method for us and re-renders the page when the responsive data is changed.
Meteor is a real-time, responsive framework, but not all of the code for is responsive within the Meteor App. I f so, your app automatically re-runs when any data changes. Instead, responsiveness only occurs in code for specific areas, which we call Computations.
In other words, the Computations code block runs based on changes in responsive data. If you have a responsive data source (for example, a Session variable) and want to respond to it in a timely manner, you need to build a Computation.
Note that you generally don't need to explicitly do this, because Meteor has let each template render its own Computation (meaning that the code and callback functions in the template Helper are responsive by default).
The responsive data source used by Computations is tracked by it so that you know when the responsive data has changed.
This is achieved through the
invalidate()
in Computations.
Computations is generally simply used to determine what's not working on a page, which usually happens in the template's Computations (although template Computations may also do some work to make the page more efficient). Of course, you can use more Computations if you want, but you might use them less in practice.
Now let's take a look at how Computations works, and it's actually surprisingly simple to set up a Computations.
All we need to do is add the required block of code to the
Tracker.autorun
method and turn it into a responsive Computations:
Meteor.startup(function() {
Tracker.autorun(function() {
console.log('There are ' + Posts.find().count() + ' posts');
});
});
Note that we need
Tracker
block
Meteor.startup()
block to make sure it runs only
Posts
Meteor completes loading the Posts collection.
In the background,
autorun
creates a Computation that automatically reruns when the data source changes. S
o we set up a very simple Computation to output the number of posts to the console.
Because
Posts.find()
responsive data source, it is responsible for telling Computation to re-run each time the number of posts changes.
> Posts.insert({title: 'New Post'});
There are 4 posts.
In summary, we can bind responsive data to code in a natural way so that the background dependency system will re-run the code at the right time.