En esta entrada vamos a ver lo sencillo que es crear un crud con Angular Meteor. Angular Meteor es un package para meteor que nos permite utilizar Angular sin colisionar dentro de Meteor.
Si te interesa una introducción a Angular Meteor a continuación te dejo un videotutorial del blog donde vemos cómo hacer la instalación y un par de cosas.
Crear el proyecto
Para crear el proyecto simplemente ejecuta el siguiente comando desde la terminal.
1 |
meteor create crud && cd crud && meteor |
Eso habrá creado y lanzado el proyecto en la url http://localhost:3000/, debes poder ver el mensaje de bienvenida, perfecto.
Instalar las dependencias con atmosphere
Ya que vamos a trabajar con AngularJS, necesitamos movernos por la aplicación y queremos un diseño decente, vamos a instalar los siguientes packages con Atmosphere.
1 |
meteor add urigo:angular angularui:angular-ui-router mrt:bootstrap-3 |
Cómo puedes ver hemos instalado Angular, ui-router y bootstrap para Meteor, esas dependencias ya serán cargadas de forma automática por meteor.
Configuración inicial, rutas y módulo con AngularJS
Elimina los tres archivos que hay en la raíz del proyecto y crea un archivo llamado app.js con el siguiente código para iniciar el proyecto.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
if(Meteor.isClient) { angular.module("app", ["angular-meteor", "ui.router"]) .config(function($urlRouterProvider, $stateProvider) { $stateProvider .state('posts', { url: '/posts', templateUrl: 'post-list.ng.html', controller: 'PostsCtrl' }) .state('postDetails', { url: '/posts/:postId', templateUrl: 'post-details.ng.html', controller: 'PostsCtrl' }) .state('postsAdd', { url: '/posts-add', templateUrl: 'post-add.ng.html', controller: 'PostsCtrl' }) .state('postsEdit', { url: '/posts/edit/:postId', templateUrl: 'post-edit.ng.html', controller: 'PostsCtrl' }); $urlRouterProvider.otherwise('/posts'); }) .controller("PostsCtrl", function($scope, $meteor, $state, $stateParams) { }) } |
Cómo puedes ver, inyectamos el módulo angular-meteor, el cuál nos permite utilizar angular y también el ui-router.
Es muy importante que todo el código de AngularJS esté dentro de la condición Meteor.isClient, de otra forma no funcionará.
La configuración de las rutas creo que es algo que no necesita explicación a estas alturas, finalmente declaramos el controlador PostsCtrl al cuál le pasamos el $scope, $meteor, $state y $stateParams, $meteor nos permitirá acceder a los datos de Mongo cómo veremos más adelante.
La vista principal
Ahora crea el archivo index.html con el siguiente código.
1 2 3 4 5 |
<body ng-app="app"> <div class="container"> <ui-view></ui-view> </div> </body> |
La directiva ui-view renderizará todas las rutas que hemos establecido en la configuración de la app.
Mostrar todos los Posts
Crea el archivo post-list.ng.html y añade el siguiente código.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<div class="col-md-12"> <h1 class="text-center text-muted">Posts List</h1> <div class="col-md-1 col-md-offset-9"> <a ui-sref="postsAdd" class="btn btn-block btn-success">Add</a> </div> <div class="col-md-2"> <button ng-click="removeAll()" class="btn btn-block btn-danger">Remove All</button> </div> <table class="table" ng-show="posts.length > 0"> <tr> <th width="30%">Title</th> <th width="50%">Body</th> <th width="10%">Edit</th> <th width="10%">Delete</th> </tr>: <tr ng-repeat="post in posts"> <td>{{ post.title }}</td> <td>{{ post.body }}</td> <td><a href="#/posts/edit/{{post._id}}" class="btn btn-small btn-info">Edit</a></td> <td><button class="btn btn-small btn-danger" ng-click="remove(post)">Delete</button></td> </tr> </table> <div class="alert alert-danger" ng-show="!posts.length">Add a new post</div> </div> |
Cómo puedes ver, simplemente es AngularJS, lo importante es ver cómo obtenemos los posts, así que añade la siguiente línea al archivo app.js antes de la condición Meteor.isClient.
1 |
Posts = new Mongo.Collection("posts"); |
De esta forma la colección posts estará disponible en el cliente y en el servidor, recordemos que todo lo que está fuera del cliente y del servidor carga en ambos sitios.
Para obtener todos los posts simplemente añade la siguiente línea dentro del controlador PostsCtrl.
1 |
$scope.posts = $meteor.collection(Posts); |
Si revisas el navegador debes ver el mensaje Add new post, asi que vamos a ello.
Crear nuevos Posts
Crea el archivo post-add.ng.html y añade el siguiente formulario html.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<div class="col-md-6 col-md-offset-3"> <h1 class="text-center text-muted">Add new post</h1> <form role="form"> <div class="form-group"> <input class="form-control" type="text" ng-model="post.title"> </div> <div class="form-group"> <textarea class="form-control" ng-model="post.body"></textarea> </div> <input type="button" ng-click="save(post)" value="Save post" class="btn btn-success btn-block"> <a href="#/posts" class="btn btn-info btn-block">Return</a> </form> </div> |
Si te fijas, tenemos un evento ng-click el cuál llama al método save, vamos a definir este método en el controlador.
1 2 3 4 5 |
$scope.save = function(post) { $scope.posts.push(post); $state.go("posts"); }; |
Demasiado simple pero suficiente, al tener disponible la variable de alcance $scope.posts simplemente con hacer push el registro será guardado en base de datos, una vez se haya guardado iremos de nuevo a la lista de posts y veremos que ya aparece el registro.
Editar los Posts
Crea el archivo post-edit.ng.html y añade el siguiente código.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<div class="col-md-6 col-md-offset-3" ng-init="edit()"> <h1 class="text-center text-muted">Update post</h1> <form role="form"> <div class="form-group"> <input class="form-control" type="text" ng-model="post.title"> </div> <div class="form-group"> <textarea class="form-control" ng-model="post.body"></textarea> </div> <input type="button" ng-click="update()" value="Update post" class="btn btn-success btn-block"> <a href="#/posts" class="btn btn-info btn-block">Return</a> </form> </div> |
Lo mismo que antes, excepto que aquí estamos utilizando la directiva ng-init para obtener el post que corresponde a esta zona, también tenemos el evento ng-click llamando al método update, veamos cómo obtener y actualizar el post.
1 2 3 4 5 6 7 8 9 10 11 |
$scope.edit = function() { //obtenemos el post y lo tenemos disponible para hacer operaciones en vivo $scope.post = $meteor.object(Posts, $stateParams.postId); $scope.update = function() { //actualizamos el post $scope.post.save(); $state.go("posts"); } }; |
Muy claro y sencillo, a través del método save actualizamos el post que tenemos actualmente.
Eliminar un Post
Para eliminar un post añade el siguiente código en el controlador PostsCtrl.
1 2 3 4 |
$scope.remove = function(post) { $scope.posts.remove(post); }; |
Eliminar todos los Posts
Para eliminar todos los posts añade el siguiente código en el controlador PostsCtrl.
1 2 3 4 |
$scope.removeAll = function() { $scope.posts.remove(); }; |
Igual que eliminar un post, la única diferencia es que no necesitamos pasar ningún objeto al método remove.
Espero que te haya parecido interesante y sencillo.