Estaremos creando una aplicación muy sencilla de votación donde el usuario puede:
meteor create pollingpolling será el nombre de nuestra nueva aplicación y se creará una carpeta llamada polling. Este comando creará lo siguiente:
| .meteor/
| client/ // Carpeta con los Archivos del Proyecto
| polling.css // Archivo CSS
| polling.html // El Tema HTML
| polling.js // javascript para el servidor
| server/
| main.js // javascript para el servidor meteorPodemos ejecutar esta aplicación, solo debemos entrar a la carpeta donde esta el proyecto y escribimos el comando para arrancar la aplicación meteor:
Meteor posee unas carpetas que están diseñadas para la organización de nuestra aplicación. Estas carpetas son:
| .meteor
| client/ // El código del proyecto y el navegador
|----- components/ // Componentes creado para nuestra aplicación
|--- poll-form.css
|--- poll-form.html
|--- poll-form.js
|--- poll.css
|--- poll.html
|--- poll.js
|----- app.body.html // Disposición de la aplicación
|----- app.head.html // HEAD del HTML
|----- app.js // Los JS del proyecto
|----- app.css // Los CSS del proyecto
| collections/ // Modelo de nuestro MongoDB
|----- polls.js // Definiendo la Collections de MongoDB
| server/ // codigo de nuestro servidor
|----- main.js // Agregando data de ejemplo y startup del server.MongoDB es muy fácil de trabajar. Crear el archivo polls.js dentro de la carpeta collections, escribimos los siguiente:
Polls = new Mongo.Collection('polls');Usamos Meteor.startup para poner en marcha el servidor.
Meteor.startup(function() {
if (Polls.find().count() === 0) {
var samplePolls = [
{
question: 'Meteor.js es Asombroso?',
choices: [
{ text: 'Claro que si!', votes: 0 },
{ text: 'Yeahh', votes: 0 },
{ text: 'No. Prefiero JS plano', votes: 0 }
]
},
{
question: 'Qué porcentaje le das a Bootstrap?',
choices: [
{ text: '10% si', votes: 0 },
{ text: '50% si', votes: 0 },
{ text: '100% si', votes: 0 }
]
}
];
_.each(samplePolls, function(poll) {
Polls.insert(poll);
});
}
});Meteor busca las referencias dentro del <head> y <body> y las combinas, estando es archivos diferentes. Vamos a crear el archivo client/app.body.html
<body>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
{{ >pollForm }}
</div>
</div>
</div>
<div class="polls">
{{ #each polls }}
{{ >poll }}
{{ /each }}
</div>
</body>{{ >pollForm }} busca el archivo con <template name="pollForm> en lo interno.
{{ #each polls }} hace un loop sobre el objeto polls y lo muetra en la vista polls.
Crea un archivo client/app.head.html
<head>
<meta charset="utf-8">
<title>App Encuestas</title>
</head>Creamos la plantilla client/components/poll-form.html
<template name="pollForm">
<form>
<div class="form-group">
<label>Pregunta</label>
<input type="text" name="question" class="form-control" placeholder="Tu Pregunta">
</div>
<div class="form-group">
<label>Opción #1</label>
<input type="text" name="choice1" class="form-control" placeholder="Opción #1">
</div>
<div class="form-group">
<label>Opción #2</label>
<input type="text" name="choice2" class="form-control" placeholder="Opción #2">
</div>
<div class="form-group">
<label>Opción #3</label>
<input type="text" name="choice3" class="form-control" placeholder="Opción #3">
</div>
<button type="submit" class="btn btn-lg btn-success btn-block">Crear Encuesta</button>
</form>
</template>Un poco CSS client/components/poll-form.css
.question-group {
margin-bottom:20px;
background:#EEE;
padding:20px;
}
.question-group label {
font-size:18px;
}Creamos archivo client/components/poll.html
<template name="poll">
<div class="poll well well-lg" data-id="{{ _id }}">
<h3>{{ question }}</h3>
{{ #each indexedArray choices }}
<a href="#" class="vote btn btn-info btn-block" data-id="{{ _index }}">
<span class="badge votes pull-right">{{ votes }}</span>
<span class="text">{{ text }}</span>
</a>
{{ /each }}
</div>
</template>
Manejamos los helper de Meteor, para conectar las distintas plantillas con el server.
Template.body.helpers({
polls: function() {
return Polls.find();
}
});
// agrega index a cada item
UI.registerHelper('indexedArray', function(context, options) {
if (context) {
return context.map(function(item, index) {
item._index = index;
return item;
});
}
});Meteor tiene una manera facil y divertida de unir eventos y variables a sus plantillas
Template.pollForm.events({
'submit form': function(event) {
event.preventDefault();
var newPoll = {
question: event.target.question.value,
choices: [
{ text: event.target.choice1.value, votes: 0 },
{ text: event.target.choice2.value, votes: 0 },
{ text: event.target.choice3.value, votes: 0 }
]
};
Polls.insert(newPoll);
}
});Dentro de client/components/poll.js, vamos a adjuntar evento a nuestra plantilla
Template.poll.events({
'click .vote': function(event) {
event.preventDefault();
var pollID = $(event.currentTarget).parent('.poll').data('id');
var voteID = $(event.currentTarget).data('id');
var voteString = 'choices.' + voteID + '.votes';
var action = {};
action[voteString] = 1;
Polls.update(
{ _id: pollID },
{ $inc: action }
);
}
});Tradicionalmente, para obtener Bootstrap, lo primero que haria es descargarlo, moverlo al proyecto y acoplarlo a mi HTML con <link>.
En Meteor, es demasiado facil instalar Bootstrap y aplicarlo automáticamente al proyecto. El bilding de Meteor.js incluirá la CSS por su cuenta.
meteor add twbs:bootstrapYa tenemos Bootstrap, ahora creemos nuestrs estilos en app.css, yo decidi utilizar Flexbox para cuadricular los formularios.
body {
padding-top:50px;
}
.polls {
display:flex;
flex-flow:row wrap;
justify-content:center;
}
.poll {
width:25%;
margin:20px;
}