{"id":2077,"date":"2015-09-02T16:42:11","date_gmt":"2015-09-02T16:42:11","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2077"},"modified":"2025-06-13T23:47:43","modified_gmt":"2025-06-14T06:47:43","slug":"using-couchbase-in-your-ionic-framework-application-part-1","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-in-your-ionic-framework-application-part-1\/","title":{"rendered":"C\u00f3mo usar Couchbase en tu aplicaci\u00f3n de Ionic Framework Parte 1"},"content":{"rendered":"<p><a href=\"https:\/\/www.ionicframework.com\">Marco i\u00f3nico<\/a> se ha convertido recientemente en uno de los frameworks m\u00f3viles m\u00e1s populares. Facilita enormemente la creaci\u00f3n de grandes interfaces de usuario para aplicaciones m\u00f3viles. Sin embargo, parte del reto consiste tambi\u00e9n en gestionar los datos, obteni\u00e9ndolos del servidor back-end y guard\u00e1ndolos localmente para cuando el dispositivo no est\u00e9 conectado.<\/p>\n<p>Couchbase Mobile se encarga de esto por ti y con el plugin de Apache Cordova, \u00a1es pan comido!<\/p>\n<p>En este tutorial aprender\u00e1s a:<\/p>\n<ul>\n<li>Incluye Couchbase Lite en tu proyecto Ionic.<\/li>\n<li>Utiliza los componentes de Ionic UI para mostrar los datos en pantalla.<\/li>\n<li>Ejecute la aplicaci\u00f3n en el simulador iOS \/ Android.<\/li>\n<\/ul>\n<h2>Requisitos previos<\/h2>\n<ul>\n<li>Ionic Framework 1.0+<\/li>\n<li>Apache Cordova 5.0+<\/li>\n<li>El SDK de Android si construyes para Android<\/li>\n<li>Un Mac con Xcode instalado si se construye para iOS<\/li>\n<\/ul>\n<h2>Primeros pasos<\/h2>\n<p>Antes de empezar a codificar es importante que creemos un nuevo proyecto y configuremos todos los plugins y componentes necesarios. Desde el s\u00edmbolo del sistema (Windows) o Terminal (Mac \/ Linux), ejecuta lo siguiente para crear un nuevo proyecto Ionic:<\/p>\n<pre><code class=\"language-bash\">\r\nionic start CouchbaseApp blank\r\ncd CouchbaseApp\r\nionic platform add android\r\nionic platform add ios\r\n<\/code><\/pre>\n<p>Recuerda que si no utilizas un Mac, no puedes a\u00f1adir ni crear para la plataforma iOS.<\/p>\n<p>Para que este proyecto tenga \u00e9xito, hay algunos <a href=\"https:\/\/cordova.apache.org\/\">Apache Cordova<\/a> que deben ser instalados. Con el proyecto Ionic como directorio de trabajo actual en el S\u00edmbolo del sistema o Terminal, ejecute los siguientes comandos:<\/p>\n<pre><code class=\"language-bash\">\r\ncordova plugin add cordova-plugin-whitelist\r\ncordova plugin add https:\/\/github.com\/couchbaselabs\/Couchbase-Lite-PhoneGap-Plugin.git\r\n<\/code><\/pre>\n<p>Esto instalar\u00e1 el plugin Apache Cordova whitelist que nos permitir\u00e1 comunicarnos con servicios externos y el plugin Couchbase PhoneGap que permitir\u00e1 usar Couchbase en nuestra aplicaci\u00f3n.<\/p>\n<h2>Inclusi\u00f3n de la biblioteca RESTful de AngularJS<\/h2>\n<p>El uso de Couchbase Lite se realiza a trav\u00e9s de las API RESTful expuestas mediante el plugin Apache Cordova. Una lista completa de estos puntos finales de la API se puede encontrar en el <a href=\"https:\/\/developer.couchbase.com\/mobile\/develop\/references\/couchbase-lite\/rest-api\/index.html\">documentaci\u00f3n oficial de Couchbase<\/a>. Sin embargo, existe un <a href=\"https:\/\/angularjs.org\/\">AngularJS<\/a> para facilitar la llamada a estos puntos finales.<\/p>\n<p>Descargar la \u00faltima <a href=\"https:\/\/github.com\/couchbaselabs\/ng-couchbase-lite\">ng-couchbase-lite<\/a> que se encuentra en GitHub e incluye el archivo <strong>ng-couchbase-lite.min.js<\/strong> que se encuentra en el archivo <strong>dist<\/strong> en el directorio <strong>www\/js\/<\/strong> carpeta.<\/p>\n<p>Con el archivo incluido en su proyecto, abra el archivo <strong>index.html<\/strong> e incluya el archivo JavaScript de la siguiente manera:<\/p>\n<pre><code class=\"language-html\">\r\n\r\n\r\n<\/code><\/pre>\n<p>Observe que la secuencia de comandos se incluy\u00f3 sobre el proyecto <strong>www\/js\/app.js<\/strong>.<\/p>\n<p>Lo \u00faltimo que hay que hacer antes de usar ng-couchbase-lite es inyectarlo en AngularJS. Esto se puede hacer abriendo el archivo <strong>www\/js\/app.js<\/strong> y cambiando el <strong>m\u00f3dulo.angular<\/strong> para que parezca lo siguiente:<\/p>\n<pre><code class=\"language-javascript\">\r\nvar couchbaseApp = angular.module(\"starter\", [\"ionic\", \"ngCouchbaseLite\"]);\r\n<\/code><\/pre>\n<p>La envoltura AngularJS ahora se puede utilizar a trav\u00e9s del proyecto.<\/p>\n<h2>Pulir el fichero \u00edndice<\/h2>\n<p>Es necesario hacer algunos ajustes en el proyecto de <strong>www\/index.html<\/strong> para aprovechar al m\u00e1ximo este tutorial. El primero de los cuales es la adici\u00f3n de alguna informaci\u00f3n meta para complementar el plugin de listas blancas. Es m\u00e1s necesario para Android que para iOS. Cerca de la otra <strong>meta<\/strong> incluya lo siguiente:<\/p>\n<pre><code class=\"language-html\">\r\n\r\n<\/code><\/pre>\n<p>Esto s\u00f3lo indica a tu proyecto que quieres trabajar con ciertos scripts.<\/p>\n<p>El otro ajuste que quieres hacer es dentro de tu <strong>cuerpo<\/strong> etiquetas. Sustituya todo lo que hay dentro del cuerpo por lo siguiente:<\/p>\n<pre><code class=\"language-html\">\r\n\r\n    \r\n    \r\n\r\n<\/code><\/pre>\n<p>Usted debe ser bueno para ir en este punto<\/p>\n<h2>Uso de una variable global de base de datos<\/h2>\n<p>Para ahorrarnos la molestia de tener que abrir la base de datos en cada vista, vamos a crear una variable global al proyecto. En el directorio <strong>www\/js\/app.js<\/strong> archivo siguiente <strong>m\u00f3dulo.angular<\/strong> incluyen lo siguiente:<\/p>\n<pre><code class=\"language-javascript\">\r\nvar todoDatabase = null;\r\n<\/code><\/pre>\n<p>Esto se establecer\u00e1 m\u00e1s tarde cuando inicialicemos la base de datos.<\/p>\n<h2>Configuraci\u00f3n del router de interfaz de usuario<\/h2>\n<p>Ionic Framework utiliza el UI-Router de AngularJS, por lo que vamos a aprovecharlo a la hora de manejar nuestras vistas y controladores. Dentro del proyecto <strong>www\/js\/app.js<\/strong> a\u00f1ada el siguiente c\u00f3digo:<\/p>\n<pre><code class=\"language-javascript\">\r\ncouchbaseApp.config(function($stateProvider, $urlRouterProvider) {\r\n    $stateProvider\r\n        .state(\"todoLists\", {\r\n            url: \"\/todoLists\",\r\n            templateUrl: \"templates\/todolists.html\",\r\n            controller: \"TodoListsController\"\r\n        })\r\n        .state(\"tasks\", {\r\n            url: \"\/tasks\/:listId\",\r\n            templateUrl: \"templates\/tasks.html\",\r\n            controller: \"TaskController\"\r\n        });\r\n    $urlRouterProvider.otherwise(\"\/todoLists\");\r\n});\r\n<\/code><\/pre>\n<p>Tenemos dos rutas, una a nuestra vista de listas y otra a nuestra vista de tareas. Sin embargo, la vista de tareas requiere un par\u00e1metro adicional que identificamos como <strong>listId<\/strong>. Esto se debe a que cuando navegamos a la vista de tareas queremos proporcionar el elemento de lista padre al que pertenece la tarea. Esto nos ayudar\u00e1 a consultar nuestros datos. Ignora los controladores por ahora, porque los crearemos m\u00e1s tarde.<\/p>\n<h2>Inicializaci\u00f3n de la base de datos y las vistas<\/h2>\n<p>Lo primero que hay que hacer cuando se utiliza el plugin PhoneGap de Couchbase es crear una base de datos. Despu\u00e9s, puedes registrar vistas para consultar los documentos que residir\u00e1n en la base de datos. Las vistas de Couchbase son consultas map\/reduce que construyen el \u00edndice incrementalmente a medida que se guardan nuevos documentos en la base de datos. Son completamente diferentes a las vistas de interfaz de usuario.<\/p>\n<p>Dentro de la secci\u00f3n <strong>www\/js\/app.js<\/strong> vamos a incluir algunas cosas en el archivo AngularJS <strong>ejecute<\/strong> m\u00e9todo:<\/p>\n<pre><code class=\"language-javascript\">\r\ncouchbaseApp.run(function($ionicPlatform, $couchbase) {\r\n    $ionicPlatform.ready(function() {\r\n        \/\/ 1\r\n        if(!window.cblite) {\r\n            alert(\"Couchbase Lite is not installed!\");\r\n        } else {\r\n            cblite.getURL(function(err, url) {\r\n                if(err) {\r\n                    alert(\"There was an error getting the database URL\");\r\n                    return;\r\n                }\r\n                todoDatabase = new $couchbase(url, \"todo\");\r\n                \/\/ 2\r\n                todoDatabase.createDatabase().then(function(result) {\r\n                    var todoViews = {\r\n                        lists: {\r\n                            map: function(doc) {\r\n                                if(doc.type == \"list\" &amp;&amp; doc.title) {\r\n                                    emit(doc._id, {title: doc.title, rev: doc._rev})\r\n                                }\r\n                            }.toString()\r\n                        },\r\n                        tasks: {\r\n                            map: function(doc) {\r\n                                if(doc.type == \"task\" &amp;&amp; doc.title &amp;&amp; doc.list_id) {\r\n                                    emit(doc.list_id, {title: doc.title, list_id: doc.list_id, rev: doc._rev})\r\n                                }\r\n                            }.toString()\r\n                        }\r\n                    };\r\n                    todoDatabase.createDesignDocument(\"_design\/todo\", todoViews);\r\n                    todoDatabase.listen();\r\n                }, function(error) {\r\n                    \/\/ There was an error creating the database\r\n                });\r\n             });\r\n         }\r\n    });\r\n});\r\n<\/code><\/pre>\n<p>Esto es lo que ocurre paso a paso:<\/p>\n<ol>\n<li>Primero compruebe que el plugin existe (instalado y en funcionamiento). Si existe, a continuaci\u00f3n, crear una nueva base de datos si la base de datos deseada no existe ya. Si la creaci\u00f3n de la base de datos es exitosa, vamos a crear dos vistas, una para obtener las listas de tareas pendientes, y otra para obtener las tareas. Para este tutorial, la base de datos que estamos creando se llama <strong>todo<\/strong>.<\/li>\n<li>Vamos a crear una vista llamada <strong>tareas<\/strong> y <strong>enumera<\/strong>tanto dentro del <strong>dise\u00f1o\/todo<\/strong> documento de dise\u00f1o. En cuanto a las vistas de Couchbase. El <strong>enumera<\/strong> devolver\u00e1 todos los documentos que tengan un <strong>tipo.doc<\/strong> de <strong>lista<\/strong> y que tienen un <strong>t\u00edtulo<\/strong> propiedad. Sin embargo, s\u00f3lo el t\u00edtulo y la revisi\u00f3n del documento se devuelven con el id del documento. Esto se hace para aligerar el proceso. La direcci\u00f3n <strong>tareas<\/strong> devolver\u00e1 todos los documentos que tengan un <strong>tipo.doc<\/strong> de <strong>tarea<\/strong> as\u00ed como algunos <strong>t\u00edtulo<\/strong> propiedad y padre <strong>lista_id<\/strong> propiedad. En esta vista en particular, s\u00f3lo se devuelven el t\u00edtulo, la revisi\u00f3n del documento y el id de la lista con el id del documento.<\/li>\n<\/ol>\n<h2>Creaci\u00f3n de los controladores<\/h2>\n<h3>Controlador de la lista de tareas<\/h3>\n<p>Dentro de la <strong>www\/js\/app.js<\/strong> de su proyecto, cree el siguiente controlador:<\/p>\n<pre><code class=\"language-javascript\">\r\ncouchbaseApp.controller(\"TodoListsController\", function($scope, $state, $ionicPopup, $couchbase, $rootScope) {\r\n\r\n    $scope.lists = { };\r\n\r\n    $scope.insert = function() { };\r\n\r\n    $scope.delete = function(list) { };\r\n\r\n});\r\n<\/code><\/pre>\n<p>Una peque\u00f1a explicaci\u00f3n sobre nuestros planes El <strong>$scope.listas<\/strong> contendr\u00e1 todos los documentos Couchbase a los que la vista en particular tendr\u00e1 acceso. <strong>$scope.insert<\/strong> por supuesto ser\u00e1 responsable de insertar datos en Couchbase Lite y <strong>$scope.delete<\/strong> se encargar\u00e1 de borrar los datos.<\/p>\n<p>As\u00ed que empezando por el <strong>$scope.insert<\/strong> funci\u00f3n:<\/p>\n<pre><code class=\"language-javascript\">\r\n$scope.insert = function() {\r\n    $ionicPopup.prompt({\r\n        title: 'Enter a new TODO list',\r\n        inputType: 'text'\r\n    })\r\n    .then(function(result) {\r\n        var obj = {\r\n            title: result,\r\n            type: \"list\",\r\n        };\r\n        todoDatabase.createDocument(obj).then(function(result) {\r\n            \/\/ The document was saved\r\n        }, function(error) {\r\n            \/\/ There was an error saving the document\r\n        });\r\n    });\r\n};\r\n<\/code><\/pre>\n<p>En lugar de crear una vista separada para insertar los datos, utilizaremos un archivo <strong>$ionicPopup<\/strong>. Con el resultado lo estamos a\u00f1adiendo a un objeto y tambi\u00e9n a\u00f1adiendo un tipo de documento para futuras referencias. A continuaci\u00f3n, este objeto se inserta en la base de datos, momento en el que se puede optar por realizar determinadas tareas en funci\u00f3n de su \u00e9xito o fracaso.<\/p>\n<p>La siguiente funci\u00f3n de la que hay que preocuparse es <strong>$scope.delete<\/strong> funci\u00f3n:<\/p>\n<pre><code class=\"language-javascript\">\r\n$scope.delete = function(list) {\r\n    var listId = list._id;\r\n    todoDatabase.deleteDocument(list._id, list._rev).then(function(result) {\r\n        todoDatabase.queryView(\"_design\/todo\", \"tasks\", {\"start_key\": listId}).then(function(result) {\r\n            for(var i = 0; i &lt; result.rows.length; i++) {\r\n                todoDatabase.deleteDocument(result.rows[i].id, result.rows[i].value.rev);\r\n            }\r\n        }, function(error) {\r\n            \/\/ There was an error querying the view\r\n        });\r\n    }, function(error) {\r\n        \/\/ There was an error deleting the list document\r\n    });\r\n};\r\n<\/code><\/pre>\n<p>Aqu\u00ed ocurren varias cosas. En primer lugar, intentamos eliminar el documento de la lista a trav\u00e9s del id y la revisi\u00f3n concretos. Si lo conseguimos, consultamos nuestra vista de tareas en busca de cualquier tarea cuyo padre sea nuestro documento reci\u00e9n creado. Acotamos nuestra b\u00fasqueda haciendo uso de la funci\u00f3n <strong>clave_inicio<\/strong> opci\u00f3n. Para cada documento de tarea que coincida, elim\u00ednelo tambi\u00e9n para que no quede hu\u00e9rfano al eliminar el documento principal.<\/p>\n<p>El par\u00e1metro que se pasa a la funci\u00f3n eliminar es un objeto.<\/p>\n<p>Pero, \u00a1un momento! \u00bfC\u00f3mo buscamos documentos para mostrarlos en nuestra lista? Lo que vamos a hacer tiene dos partes. La primera consiste en consultar la vista que creamos al crear una nueva base de datos. Esto se puede hacer de la siguiente manera:<\/p>\n<pre><code class=\"language-javascript\">\r\ntodoDatabase.queryView(\"_design\/todo\", \"lists\").then(function(result) {\r\n    for(var i = 0; i &lt; result.rows.length; i++) {\r\n        $scope.lists[result.rows[i].id] = result.rows[i].value;\r\n    }\r\n}, function(error) {\r\n    \/\/ There was an error querying the view\r\n});\r\n<\/code><\/pre>\n<p>Esto buscar\u00e1 listas de tareas en la vista cuando \u00e9sta se cargue, pero \u00bfc\u00f3mo buscar cambios constantemente? Desde que empezamos a escuchar los cambios en el <strong>ejecute<\/strong> podemos elegir mostrar lo que hemos o\u00eddo:<\/p>\n<pre><code class=\"language-javascript\">\r\n$rootScope.$on(\"couchbase:change\", function(event, args) {\r\n    for(var i = 0; i &lt; args.results.length; i++) {\r\n        if(args.results[i].hasOwnProperty(\"deleted\") &amp;&amp; args.results[i].deleted === true) {\r\n            delete $scope.lists[args.results[i].id];\r\n        } else {\r\n            if(args.results[i].id.indexOf(\"_design\") === -1) {\r\n                todoDatabase.getDocument(args.results[i].id).then(function(result) {\r\n                    if(result.type === \"list\") {\r\n                        $scope.lists[result._id] = result;\r\n                    }\r\n                });\r\n            }\r\n        }\r\n    }\r\n});\r\n<\/code><\/pre>\n<p>El c\u00f3digo anterior escuchar\u00e1 el <strong>couchbase:cambiar<\/strong> evento. Si se activa, har\u00e1 un bucle a trav\u00e9s de todos los cambios y determinar\u00e1 si va a borrar un documento de la lista o si va a insertar un documento en la lista. Digo upserting porque lo insertar\u00e1 si no existe o lo actualizar\u00e1 si existe.<\/p>\n<h3>El controlador de hojas de ruta<\/h3>\n<p>Dentro de la <strong>www\/js\/app.js<\/strong> de su proyecto, cree el siguiente controlador:<\/p>\n<pre><code class=\"language-javascript\">\r\ncouchbaseApp.controller(\"TaskController\", function($scope, $rootScope, $stateParams, $ionicPopup, $ionicHistory, $couchbase) {\r\n\r\n    $scope.todoList = $stateParams.listId;\r\n\r\n    $scope.tasks = { };\r\n\r\n    $scope.insert = function() { };\r\n\r\n    $scope.delete = function(task) { };\r\n\r\n    $scope.back = function() { };\r\n\r\n});\r\n<\/code><\/pre>\n<p>Aqu\u00ed est\u00e1n ocurriendo algunas cosas. El <strong>$scope.todoList<\/strong> contiene el identificador de la lista que se pas\u00f3 desde la vista anterior de la lista de tareas. Es el identificador de la lista seleccionada. En <strong>$scope.tasks<\/strong> es similar a lo que vimos en el <strong>TodoListsController<\/strong> con el <strong>$scope.listas<\/strong> objeto. Esta vez s\u00f3lo almacenar\u00e1 informaci\u00f3n sobre la tarea. La direcci\u00f3n <strong>$scope.insert<\/strong> y <strong>$scope.delete<\/strong> tambi\u00e9n ser\u00e1 muy similar a lo que vimos en el <strong>TodoListsController<\/strong>. Sin embargo, <strong>$scope.volver<\/strong> es nuevo y se encarga de llevarnos un nivel hacia atr\u00e1s en la pila del historial al pulsar la flecha hacia atr\u00e1s dentro de la aplicaci\u00f3n.<\/p>\n<p>As\u00ed que vamos a llenar estas funciones con un poco de c\u00f3digo, comenzando con el <strong>$scope.insert<\/strong> funci\u00f3n:<\/p>\n<pre><code class=\"language-javascript\">\r\n$scope.insert = function() {\r\n    $ionicPopup.prompt({\r\n        title: 'Enter a new TODO task',\r\n        inputType: 'text'\r\n    })\r\n    .then(function(result) {\r\n        var obj = {\r\n            title: result,\r\n            type: \"task\",\r\n            list_id: $stateParams.listId,\r\n        };\r\n        todoDatabase.createDocument(obj).then(function(result) {\r\n            \/\/ The task was created successfully\r\n        }, function(error) {\r\n            \/\/ There was an error creating the task\r\n        });\r\n    });\r\n};\r\n<\/code><\/pre>\n<p>Al igual que en el otro controlador, \u00e9ste tambi\u00e9n utilizar\u00e1 la funci\u00f3n <strong>$ionicPopup<\/strong> para introducir datos. El resultado se a\u00f1adir\u00e1 a un objeto con un tipo y el id de la lista a la que pertenece esta tarea secundaria. A continuaci\u00f3n, este objeto se inserta en la base de datos.<\/p>\n<p>Lo siguiente es la funcionalidad de borrado para eliminar tareas de Couchbase Lite:<\/p>\n<pre><code class=\"language-javascript\">\r\n$scope.delete = function(task) {\r\n    todoDatabase.deleteDocument(task._id, task._rev);\r\n}\r\n<\/code><\/pre>\n<p>F\u00edjate en lo mucho m\u00e1s f\u00e1cil que resulta esta funci\u00f3n de borrado en comparaci\u00f3n con el borrado de listas. Esto se debe a que no tenemos que preocuparnos por los datos hu\u00e9rfanos. S\u00f3lo hay que introducir el id de la tarea y la revisi\u00f3n a borrar y ya est\u00e1.<\/p>\n<p>Volviendo a la funci\u00f3n back encargada de devolvernos a la lista de tareas pendientes:<\/p>\n<pre><code class=\"language-javascript\">\r\n$scope.back = function() {\r\n    $ionicHistory.goBack();\r\n}\r\n<\/code><\/pre>\n<p>Nada especial aqu\u00ed, pero es importante porque los dispositivos iOS no tienen un bot\u00f3n de retroceso de hardware. Menos importante para Android, pero todav\u00eda bueno tener para la consistencia.<\/p>\n<p>Al igual que con nuestro controlador de lista de tareas, tenemos que preocuparnos de presentar los datos en pantalla. De hecho ser\u00e1 muy similar a lo que vimos en el otro controlador. Empezando por consultar la vista de tareas:<\/p>\n<pre><code class=\"language-javascript\">\r\ntodoDatabase.queryView(\"_design\/todo\", \"tasks\", {\"start_key\": $stateParams.listId}).then(function(result) {\r\n    for(var i = 0; i &lt; result.rows.length; i++) {\r\n        $scope.tasks[result.rows[i].id] = {\"_id\": result.rows[i].id, \"title\": result.rows[i].value.title, \"list_id\": result.rows[i].value.list_id, \"_rev\": result.rows[i].value.rev};\r\n    }\r\n}, function(error) {\r\n    \/\/ There was an error querying the view\r\n});\r\n<\/code><\/pre>\n<p>En el c\u00f3digo anterior estamos consultando la vista, pero tambi\u00e9n comprobando que los resultados del documento comparten el mismo padre de la lista de tareas, mediante el uso de la propiedad <strong>clave_inicio<\/strong>. Si los resultados coinciden, a\u00f1\u00e1dalos a nuestro objeto de tareas.<\/p>\n<p>En cuanto a nuestro oyente, de nuevo ser\u00e1 muy similar a lo que ya hemos visto:<\/p>\n<pre><code class=\"language-javascript\">\r\n$rootScope.$on(\"couchbase:change\", function(event, args) {\r\n    for(var i = 0; i &lt; args.results.length; i++) {\r\n        if(args.results[i].hasOwnProperty(\"deleted\") &amp;&amp; args.results[i].deleted === true) {\r\n            delete $scope.tasks[args.results[i].id];\r\n        } else {\r\n            if(args.results[i].id.indexOf(\"_design\") === -1) {\r\n                todoDatabase.getDocument(args.results[i].id).then(function(result) {\r\n                    if(result.type === \"task\") {\r\n                        $scope.tasks[result._id] = result;\r\n                    }\r\n                });\r\n            }\r\n        }\r\n    }\r\n});\r\n<\/code><\/pre>\n<p>En lugar de filtrar por listas, filtramos por tareas.<\/p>\n<h2>Creaci\u00f3n de vistas de interfaz<\/h2>\n<p>Habr\u00e1 dos vistas en esta aplicaci\u00f3n:<\/p>\n<ul>\n<li>Una vista para crear, visualizar y eliminar listas<\/li>\n<li>Una vista para crear, visualizar y eliminar tareas<\/li>\n<\/ul>\n<p>El dise\u00f1o y la funcionalidad entre ambos ser\u00e1n casi id\u00e9nticos. Si un <strong>www\/plantillas<\/strong> no existe ya en tu proyecto, cr\u00e9alo.<\/p>\n<h3>Vista de la lista de tareas<\/h3>\n<p>En la secci\u00f3n <strong>www\/plantillas<\/strong>cree un nuevo archivo llamado <strong>todolistas.html<\/strong> y a\u00f1ade el siguiente c\u00f3digo:<\/p>\n<pre><code class=\"language-html\">\r\n\r\n    \r\n        <button class=\"right button button-icon icon ion-plus\"><\/button>\r\n    \r\n    \r\n        \r\n            \r\n                {{value.title}}\r\n                \r\n            \r\n        \r\n    \r\n\r\n<\/code><\/pre>\n<p>Hay que tener en cuenta algunas cosas sobre lo que se ve arriba. En primer lugar, habr\u00e1 un bot\u00f3n de navegaci\u00f3n con un icono m\u00e1s que ser\u00e1 la forma en que los usuarios crean nuevas listas. Al hacer clic, se llamar\u00e1 a la <strong>insertar()<\/strong> que hemos creado en nuestro controlador. La siguiente cosa a notar es c\u00f3mo hemos elegido crear nuestro m\u00e9todo <strong>lista de iones<\/strong>. Hemos optado por darle funciones de deslizamiento similares a las aplicaciones de correo comunes para iOS y Android. Esto se combina con la funci\u00f3n <strong>ion-option-button<\/strong> que usaremos para borrar listas.<\/p>\n<p>El \u00faltimo punto de este punto de vista es la <strong>ng-repeat<\/strong> que utilizamos para recorrer todas las listas. Cuando hacemos clic en un elemento de la lista, el id de la lista se pasa a trav\u00e9s de la variable <strong>ui-sref<\/strong> llamar.<\/p>\n<h3>Vista de la lista de tareas<\/h3>\n<p>En la secci\u00f3n <strong>www\/plantillas<\/strong>cree un nuevo archivo llamado <strong>tareas.html<\/strong> y a\u00f1ade el siguiente c\u00f3digo:<\/p>\n<pre><code class=\"language-html\">\r\n\r\n    \r\n        <button class=\"left button button-icon icon ion-arrow-left-c\"><\/button>\r\n    \r\n    \r\n        <button class=\"right button button-icon icon ion-plus\"><\/button>\r\n    \r\n    \r\n        \r\n            \r\n                {{value.title}}\r\n                \r\n            \r\n        \r\n    \r\n\r\n<\/code><\/pre>\n<p>De nuevo, es muy similar a la vista de lista de tareas. Sin embargo, hay dos diferencias importantes entre las dos. En primer lugar, observe que esta vista tiene un bot\u00f3n izquierdo con un icono de flecha que llama a nuestro <strong>atr\u00e1s()<\/strong> m\u00e9todo. Ahora tenemos dos botones de men\u00fa en esta pantalla. En segundo lugar, observe el bot\u00f3n <strong>ng-if<\/strong> que existe en la repetici\u00f3n <strong>ion-item<\/strong> etiqueta. S\u00f3lo queremos mostrar la tarea si tiene un padre que coincida con la lista que hemos elegido.<\/p>\n<h2>Probar el proyecto<\/h2>\n<h3>Pruebas para Android<\/h3>\n<p>Con un dispositivo conectado o un simulador en ejecuci\u00f3n, desde el s\u00edmbolo del sistema o el terminal, ejecute los dos comandos siguientes para crear e instalar el archivo APK:<\/p>\n<pre><code class=\"language-bash\">\r\nionic build android\r\nadb install -r platforms\/android\/build\/outputs\/apk\/android-debug.apk\r\n<\/code><\/pre>\n<h3>Pruebas para iOS<\/h3>\n<p>Hay dos buenas maneras de hacer esto. Puedes construir el proyecto y abrirlo con Xcode, o puedes construir y emular la aplicaci\u00f3n sin lanzar Xcode. El primero se puede hacer as\u00ed:<\/p>\n<pre><code class=\"language-bash\">\r\nionic build ios\r\n<\/code><\/pre>\n<p>A continuaci\u00f3n, abra el proyecto <strong>plataforma\/ios\/<\/strong> e inicie el archivo de proyecto de Xcode.<\/p>\n<p>Si ha instalado el paquete Node Package Manager (NPM) <strong>ios-sim<\/strong>puede hacer lo siguiente:<\/p>\n<pre><code class=\"language-bash\">\r\nionic build ios\r\nionic emulate ios\r\n<\/code><\/pre>\n<h3>Resolver cualquier problema de dependencia de Gradle<\/h3>\n<p>En tiempo de compilaci\u00f3n para Android, puede encontrarse con el siguiente mensaje de error:<\/p>\n<pre>Error: duplicate files during packaging of APK<\/pre>\n<p>Para solucionarlo, debe ampliar el archivo de compilaci\u00f3n de Gradle para Android como se indica en el documento <a href=\"https:\/\/cordova.apache.org\/docs\/en\/5.0.0\/guide_platforms_android_tools.md.html\">documentaci\u00f3n oficial de Apache Cordova<\/a>.<\/p>\n<p>Cree <strong>platforms\/android\/build-extras.gradle<\/strong> en tu proyecto y a\u00f1ade lo siguiente:<\/p>\n<pre>android {\r\n    packagingOptions {\r\n        exclude 'META-INF\/ASL2.0'\r\n        exclude 'META-INF\/LICENSE'\r\n        exclude 'META-INF\/NOTICE'\r\n    }\r\n}<\/pre>\n<h2>Conclusi\u00f3n<\/h2>\n<p>Usando el plugin PhoneGap de Couchbase, hemos creado una aplicaci\u00f3n m\u00f3vil de listas de tareas que realiza todas las transacciones localmente. Usamos AngularJS para conectarnos f\u00e1cilmente a los endpoints RESTful que Couchbase Lite expone.<\/p>\n<p>En <a href=\"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-in-your-ionic-framework-application-part-2\/\">siguiente tutorial de Ionic Framework en esta serie<\/a> repasar\u00e1 c\u00f3mo replicar datos entre el dispositivo local y Couchbase Sync Gateway para que los datos puedan ser compartidos entre dispositivos y plataformas.<\/p>\n<p>Esta serie puede descargarse \u00edntegramente de <a href=\"https:\/\/github.com\/couchbaselabs\/todolite-ionic\">Couchbase Labs GitHub<\/a> p\u00e1gina.<\/p>","protected":false},"excerpt":{"rendered":"<p>Ionic Framework has recently become one of the hottest mobile frameworks around. It makes it incredibly easy to write great user interfaces for mobile applications. However, part of the challenge is also managing data, fetching from the back-end server and [&hellip;]<\/p>","protected":false},"author":63,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[2370,7667],"tags":[1535,1534,1536],"ppma_author":[9032],"class_list":["post-2077","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android","category-couchbase-lite","tag-apache-cordova","tag-ionic-framework","tag-ios"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.1 (Yoast SEO v26.1.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using Couchbase in Your Ionic Framework Application Part 1<\/title>\n<meta name=\"description\" content=\"How to include Couchbase Lite in Ionic project and use the Ionic UI components to display the data onscreen,run the application on iOS\/Android simulator.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-in-your-ionic-framework-application-part-1\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using Couchbase in Your Ionic Framework Application Part 1\" \/>\n<meta property=\"og:description\" content=\"How to include Couchbase Lite in Ionic project and use the Ionic UI components to display the data onscreen,run the application on iOS\/Android simulator.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-in-your-ionic-framework-application-part-1\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/thepolyglotdeveloper\" \/>\n<meta property=\"article:published_time\" content=\"2015-09-02T16:42:11+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T06:47:43+00:00\" \/>\n<meta name=\"author\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nraboy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Using Couchbase in Your Ionic Framework Application Part 1\",\"datePublished\":\"2015-09-02T16:42:11+00:00\",\"dateModified\":\"2025-06-14T06:47:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/\"},\"wordCount\":2246,\"commentCount\":104,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"apache cordova\",\"ionic framework\",\"ios\"],\"articleSection\":[\"Android\",\"Couchbase Lite\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/\",\"name\":\"Using Couchbase in Your Ionic Framework Application Part 1\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2015-09-02T16:42:11+00:00\",\"dateModified\":\"2025-06-14T06:47:43+00:00\",\"description\":\"How to include Couchbase Lite in Ionic project and use the Ionic UI components to display the data onscreen,run the application on iOS\/Android simulator.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using Couchbase in Your Ionic Framework Application Part 1\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\",\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"caption\":\"Nic Raboy, Developer Advocate, Couchbase\"},\"description\":\"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.\",\"sameAs\":[\"https:\/\/www.thepolyglotdeveloper.com\",\"https:\/\/www.facebook.com\/thepolyglotdeveloper\",\"https:\/\/x.com\/nraboy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/nic-raboy-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"C\u00f3mo usar Couchbase en tu aplicaci\u00f3n de Ionic Framework Parte 1","description":"C\u00f3mo incluir Couchbase Lite en un proyecto Ionic y utilizar los componentes Ionic UI para mostrar los datos en pantalla, ejecutar la aplicaci\u00f3n en un simulador iOS\/Android.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-in-your-ionic-framework-application-part-1\/","og_locale":"es_MX","og_type":"article","og_title":"Using Couchbase in Your Ionic Framework Application Part 1","og_description":"How to include Couchbase Lite in Ionic project and use the Ionic UI components to display the data onscreen,run the application on iOS\/Android simulator.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/using-couchbase-in-your-ionic-framework-application-part-1\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2015-09-02T16:42:11+00:00","article_modified_time":"2025-06-14T06:47:43+00:00","author":"Nic Raboy, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@nraboy","twitter_misc":{"Written by":"Nic Raboy, Developer Advocate, Couchbase","Est. reading time":"12 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Using Couchbase in Your Ionic Framework Application Part 1","datePublished":"2015-09-02T16:42:11+00:00","dateModified":"2025-06-14T06:47:43+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/"},"wordCount":2246,"commentCount":104,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["apache cordova","ionic framework","ios"],"articleSection":["Android","Couchbase Lite"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/","url":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/","name":"C\u00f3mo usar Couchbase en tu aplicaci\u00f3n de Ionic Framework Parte 1","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2015-09-02T16:42:11+00:00","dateModified":"2025-06-14T06:47:43+00:00","description":"C\u00f3mo incluir Couchbase Lite en un proyecto Ionic y utilizar los componentes Ionic UI para mostrar los datos en pantalla, ejecutar la aplicaci\u00f3n en un simulador iOS\/Android.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-in-your-ionic-framework-application-part-1\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Using Couchbase in Your Ionic Framework Application Part 1"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"El blog de Couchbase","description":"Couchbase, la base de datos NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1","name":"Nic Raboy, Defensor del Desarrollador, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354","url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","caption":"Nic Raboy, Developer Advocate, Couchbase"},"description":"Nic Raboy es un defensor de las tecnolog\u00edas modernas de desarrollo web y m\u00f3vil. Tiene experiencia en Java, JavaScript, Golang y una variedad de frameworks como Angular, NativeScript y Apache Cordova. Nic escribe sobre sus experiencias de desarrollo relacionadas con hacer el desarrollo web y m\u00f3vil m\u00e1s f\u00e1cil de entender.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/es\/author\/nic-raboy-2\/"}]}},"authors":[{"term_id":9032,"user_id":63,"is_guest":0,"slug":"nic-raboy-2","display_name":"Nic Raboy, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","author_category":"","last_name":"Raboy","first_name":"Nic","job_title":"","user_url":"https:\/\/www.thepolyglotdeveloper.com","description":"Nic Raboy es un defensor de las tecnolog\u00edas modernas de desarrollo web y m\u00f3vil. Tiene experiencia en Java, JavaScript, Golang y una variedad de frameworks como Angular, NativeScript y Apache Cordova. Nic escribe sobre sus experiencias de desarrollo relacionadas con hacer el desarrollo web y m\u00f3vil m\u00e1s f\u00e1cil de entender."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2077","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=2077"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2077\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=2077"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=2077"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=2077"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=2077"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}