1- Rapid development, by writing less code
2- One Language everywhere (JS)
3- Reactive rendering html templates for single page apps
4- Single code for web & mobile
5- it has built in package management
6- Live clients, always connected [server push to clients instantly, through publish/subscriber]
and here is my first from scratch app using meteor.
I'll keep this short and cut to chase and I'll go in details when required
Source code here :
https://github.com/blabadi/meteor101-blog
you should first do:
1- install meteor
2- make directory for the project
A. Project skeleton:
navigate to the project directory and run
> meteor create meteor101
you will get 3 files and folder called .meteor
delete the 3 files and create the following dirs:
Meteor Tip:> client folder will contain client exclusive code - logic/templates/views (pages)/css..
Meteor is a convention over configuration framework, for example specific names for folders in the project structure indicate something and where this code belongs to, and we will get to that.
> server will contain server exclusive code - our security checks and authorization and where database is manipulated
> lib will contain common code, things that are shared between server and client, like collections
& router
Meteor Tip:
Unlike other usual web frameworks, meteor share code between server and client and on each side that code is handled differently internally, that makes meteor capable to simulating the result of a server action without waiting for it to complete to make UI more responsive
Now the point of this app is to make a simple single page app, where u see list of departments and employees for each department (no css here - just tried to test bootstrap vertical navigation menu):
B. Project Data :
let's define our data model :
Meteor Tip:
Meteor currently uses Mongo db which is a non relational database that stores data in json format arrays and objects.
we need departments, employees, so in the lib directory we create collections.js file that contains :
Meteor Tip:
Collections in meteor are reactive, that means if they change they will trigger any watcher to recalculate, i.e. it will be re-evaluated and any html template that uses it will be re-rendered.
and let's fill these with data initially.
in the server folder create [ bootstrap.js ] which is a file that contains stuff to do when the server start:
basically we insert departments and for each department we insert its employees connected togather with depId property.
Meteor Tip :
Meteor.startup( ) can be used to do stuff on client side, but here it only executes on server because it's under server dir.
Meteor Tip:
By default meteor adds autopublish feature (package) for every new project, which means that clients will always be updated when any collection is modified by other clients or itself, this is good for prototyping but in real apps, we will use publish / subscribe to make sure we control data access correctly and not anyone can see all data.
ok now let's do some client stuff
A. General layout for application
in single page apps or other apps, there is usually common sections in the page that don't change like header and navigation menu and footer, so a good way to do that in meteor will need two things"
1- router, that will controll navigation between different templates and controls what to show and what to remove
2-a layout template to be used as general layout, this will always be displayed on the page, and it contains common sections and the place holder for the variable template to be shown.
Meteor Tip :
Meteor like other UI frameworks uses html templates to render pages, a Template is an html with place holders and simple logic to control the UI elements based on the data context that it owns.
Templates in meteor have this syntax :
<template name="employee">
<div>
your html between template tags
and place holders are like this
<span> employee name : {{name}}</span>
</div>
</template>
to add our first template, under the client directory create folder : templates
and under that create main.html
set contents of the main app template to:
break down:
header part is for now simple static content
then we have the nav-menu div contains {{> nav}} which means render here another template called nav [will list its content next]
and the last div is the content, which will be specified by the router based on the url requested by the user [we will come to routing in next sections]
first let's create nav.html to make our navigation menu:
break down :
the template file only contains <template> , it's not an html page.
our menu is a simple <ul> tag with bootstrap css classes added
to add bootstrap to the project navigate to the project directory and run
> meteor add twbs:bootstrap
in the navigation menu we iterate over the departments (deps) and render them in list item <li>
and make them as links, and the value of the url to be evaluated by the router (comming next)
the text of this link is the department name
in case we are currently in this department page (it's selected, we add the active css class)
let's ignore the part related to the router and the selected if statement
first let's ask where will we get our data?
Meteor Tip:
each template has js helpers, that provide it with data and control it's variables.
so let's create nav.js under templates dir to control and provide this template with data:
note Template.nav (the 'nav' is comming from the <template name="nav">)
note 'deps' matches {{#each deps}} above
note we used Deps collection defined in collections.js
the 'selected' is a variable we defined that its value is a result of checking if the Session variable 'selectedDepartment' equals to the globally set _id (set by the router)
Meteor Tip:
Session is a global namespace to store variable used in the templates and it's a reactive storage, that means if it changes because of an event, then any template that depends on it will be re-rendered to reflect the new value.
ok so you're now saying what is the router, to create your router, under the lib directory create router.js
but before that execute :
> meteor add iron:router
Router:
In web frameworks a router is a module that handles mapping urls to pages..for example /department will display department.php, but here we are in a single page app, and we talk with templates, but we still want to have different urls when the user navigates, for example I want the home page to display a dashboard of all departments and all employees.
and when the user selects a department I want the url to look like this localhost:3000/department/{id}
to achive that in meteor we added iron router package.
now inside router.js add :
break down:
the first part is to tell meteor to use the template called 'main' as a general layout
the second line defines a route with name dash-board [we will define it next]
the template for that dash-board.html:
nothing fancy just static content
the third part is to define the department details.. the template for this route (dep-detail.html) is :
and the router here does two things :
1- defines url pattern (path)
2- provides the data to the template by extracting the _id from the url
3- sets the global selectedDepartment session variable that is used to determine which department
is selected in the nav menu above and assign the proper css class to it.
if we go back to the nav template above, we see that when we listed the departments that we refered to this route by name, and the router is smart enough to know that the _id needed in the path should be extracted from the department object in the nav template.
and the result url will be /department/{{_id}}
now in depDetails template we are using the data prepare in the router and displaying it.
and the other thing we do as well, is render a template called employees
that template contains :
employees.html
employees.js :
the important thing here to note is what this._id equals?
the employees template is rendered within the depDetails template, and the _id refers to the department that we are currently rendering.
now each employee is rendered in an employee template:
and this template gets its data passed from the employees template.
Read more here :
data contexts and templates :
1- https://www.discovermeteor.com/blog/a-guide-to-meteor-templates-data-contexts/
Routing :
2-http://meteortips.com/second-meteor-tutorial/iron-router-part-2/
3-https://www.meteor.com/tutorials/blaze/creating-an-app