Compartir a través de


Plantilla de EmberJS

por Xinyang Xing

La plantilla MVC de EmberJS está escrita por Nathan Totten, Thiago Santos y Xinyang Storage.

Descarga de la plantilla MVC de EmberJS

La plantilla de SPA de EmberJS está diseñada para empezar a crear rápidamente aplicaciones web interactivas del lado cliente mediante EmberJS.

"Aplicación de página única" (SPA) es el término general para una aplicación web que carga una sola página HTML y después la actualiza dinámicamente, en lugar de cargar páginas nuevas. Tras la carga inicial de la página, la SPA habla con el servidor a través de solicitudes AJAX.

Diagram that shows two boxes labeled Client and Server. An arrow labeled AJAX goes from Client to Server. An arrow labeled H T M L and an arrow labeled J SON go from Server to Client.

AJAX no es nada nuevo, pero hoy en día existen marcos de JavaScript que facilitan la tarea de compilar y mantener una gran aplicación SPA sofisticada. Además, HTML 5 y CSS3 están facilitando la creación de interfaces de usuario enriquecidas.

La plantilla SPA de EmberJS usa la biblioteca de JavaScript de Ember para controlar las actualizaciones de páginas de las solicitudes de AJAX. Ember.js usa el enlace de datos para sincronizar la página con los datos más recientes. De esta forma, no tendrá que escribir nada del código que recorre los datos JSON y actualiza el DOM. En su lugar, se colocan atributos declarativos en el HTML que indican a Ember.js cómo presentar los datos.

En el lado servidor, la plantilla EmberJS es casi idéntica a la plantilla SPA de KnockoutJS. Usa ASP.NET MVC para servir documentos HTML y ASP.NET Web API para controlar las solicitudes de AJAX desde el cliente. Para obtener más información sobre esos aspectos de la plantilla, consulte la documentación de la plantilla KnockoutJS. Este tema se centra en las diferencias entre la plantilla Knockout y la plantilla EmberJS.

Creación de un proyecto de plantilla de SPA de EmberJS

Descargue e instale la plantilla haciendo clic en el botón Descargar. Es posible que tenga que reiniciar Visual Studio.

En el panel Plantillas, seleccione Plantillas instaladas y expanda el nodo Visual C#. En Visual C#, seleccione Web. En la lista de plantillas de proyecto, seleccione Aplicación web ASP.NET MVC 4. Proporcione un nombre al proyecto y haga clic en Aceptar.

Screenshot that shows the New Project dialog box. The A S P dot NET M V C 4 Web Application template is selected.

En el asistente Nuevo proyecto, seleccione Proyecto SPA de Ember.js.

Screenshot that shows the New A S P dot NET M V C 4 Project dialog box. The Ember dot j s S P A Project template is selected.

Introducción a la plantilla de SPA de EmberJS

La plantilla EmberJS usa una combinación de jQuery, Ember.js, Handlebars.js para crear una interfaz de usuario fluida e interactiva.

Ember.js es una biblioteca de JavaScript que usa un patrón MVC del lado cliente.

  • Una plantilla, escrita en el lenguaje de plantillas Handlebars, describe la interfaz de usuario de la aplicación. En el modo de versión, el compilador de Handlebars se usa para agrupar y compilar la plantilla de controladores.
  • Un modelo almacena los datos de la aplicación que obtiene del servidor (listas ToDo y elementos ToDo).
  • Un controlador almacena el estado de la aplicación. Los controladores suelen presentar datos de modelo a las plantillas correspondientes.
  • Una vista traduce eventos primitivos de la aplicación y los pasa al controlador.
  • Un enrutador administra el estado de la aplicación, manteniendo sincronizadas las direcciones URL y las plantillas.

Además, la biblioteca de datos Ember se puede usar para sincronizar objetos JSON (obtenidos del servidor a través de una API RESTful) y los modelos de cliente.

La plantilla SPA de EmberJS organiza los scripts en ocho capas:

  • webapi_adapter.js, webapi_serializer.js: amplía la biblioteca de datos de Ember para trabajar con ASP.NET Web API.
  • Scripts/helpers.js: define nuevos asistentes Handlebars de Ember.
  • Scripts/app.js: crea la aplicación y configura el adaptador y el serializador.
  • Scripts/app/models/*.js: define los modelos.
  • Scripts/app/views/*.js: define las vistas.
  • Scripts/app/controllers/*.js: define los controladores.
  • Scripts/app/routes, Scripts/app/router.js: define las rutas.
  • Templates/*.hbs: define las plantillas de Handlebars.

Echemos un vistazo a algunos de estos scripts con más detalle.

Modelos

Los modelos se definen en la carpeta Scripts/app/models. Hay dos archivos de modelo: todoItem.js y todoList.js.

todo.model.js define los modelos del lado del cliente (explorador) para las listas de tareas pendientes. Existen dos clases de modelos: todoItem y todoList. En Ember, los modelos son subclases de DS.Model. Un modelo puede tener propiedades con atributos:

todoItemId: attr('number'), 
title: attr('string')

Los modelos pueden definir relaciones con otros modelos:

todoList: DS.belongsTo('App.TodoList'),

Los modelos pueden tener propiedades calculadas que se enlazan a otras propiedades:

hasError: function () {
    var currentError = this.get("error");
    return !(currentError === '' || currentError === null);
}.property('error'),

Los modelos pueden tener funciones de observador, que se invocan cuando cambia una propiedad observada:

saveCheckbox: function () {
    if(this.get("isDirty")){
        if (this.get("todoItemId")) {
            App.store.commit();
        }
    }
}.observes('isDone'),

Vistas

Las vistas se definen en la carpeta Scripts/app/views. Una vista traduce los eventos de la interfaz de usuario de la aplicación. Un controlador de eventos puede volver a llamar a las funciones del controlador o simplemente llamar directamente al contexto de datos.

Por ejemplo, el código siguiente procede de Views/TodoItemEditView.js. Define el control de eventos para un campo de texto de entrada.

App.TodoItemEditView = Em.TextField.extend({
    lastValue: '',
    focusIn: function (evt) {
        this.lastValue = this.get('parentView').templateData.view.content.get("title");
    },
    focusOut: function (evt) {
        this.changeContent();
    },

    insertNewline: function (evt) {
        $(evt.target).blur();
    },

    changeContent: function () {
        var todoItem = this.get('parentView').templateData.view.content;
        var newValue = todoItem.get("title");
        if (this.lastValue != newValue) {
            App.store.commit();
            this.lastValue = newValue;
        }
    }
});

Controlador

Los controladores se definen en la carpeta Scripts/app/controllers. Para representar un único modelo, extienda Ember.ObjectController:

App.TodoItemController = Ember.ObjectController.extend({
});

Un controlador también puede representar una colección de modelos mediante la extensión de Ember.ArrayController. Por ejemplo, TodoListController representa una matriz de objetos todoList. El controlador ordena por identificador de todoList, en orden descendente:

App.TodoListController = Ember.ArrayController.extend({
    error: "",
    sortProperties: ['todoListId'],
    sortAscending: true,

    // ...

El controlador define una función denominada addTodoList, que crea una nueva todoList y la agrega a la matriz. Para ver cómo se llama a esta función, abra el archivo de plantilla denominado todoListTemplate.html, en la carpeta Plantillas. El código de plantilla siguiente enlaza un botón a la función addTodoList:

<input type="button" {{action "addTodoList"}} class="isActive" value="Add Todo list"></input>

El controlador también contiene una propiedad error, que contiene un mensaje de error. Este es el código de plantilla para mostrar el mensaje de error (también en todoListTemplate.html):

<p class="error">{{error}}</p>

Rutas

Router.js define las rutas y la plantilla predeterminada para mostrar, configura el estado de la aplicación y compara las direcciones URL con las rutas:

App.Router.map(function () {
    this.route("index", { path: "/" });
    this.route("about");
    this.route("todoList", { path: "/todo" });
});

TodoListRoute.js carga datos para TodoListRoute reemplazando la función setupController:

App.TodoListRoute = Ember.Route.extend({
    setupController: function (controller, model) {
        controller.set('content', App.TodoList.find());
    }
});

Ember usa convenciones de nomenclatura para buscar coincidencias con direcciones URL, nombres de ruta, controladores y plantillas. Para más información, consulte http://emberjs.com/guides/routing/defining-your-routes/ en la documentación de EmberJS.

Templates (Plantillas [C++])

La carpeta Templates contiene cuatro plantillas:

  • application.hbs: plantilla predeterminada que se representa cuando se inicia la aplicación.
  • about.hbs: plantilla para la ruta "/about".
  • index.hbs: plantilla para la ruta raíz "/".
  • todoList.hbs: plantilla para la ruta "/todo".
  • _navbar.hbs: la plantilla define el menú de navegación.

La plantilla de aplicación actúa como una página maestra. Contiene un encabezado, un pie de página y un "{{outlet}}" para insertar otras plantillas en dependiendo de la ruta. Para más información sobre las plantillas de aplicación en Ember, consulte http://guides.emberjs.com/v1.10.0/templates/the-application-template//.

La plantilla "/todoList" contiene dos expresiones de bucle. El bucle exterior es {{#each controller}} y el bucle interior es {{#each todos}}. El código siguiente muestra una vista Ember.Checkbox integrada, un App.TodoItemEditView personalizado y un vínculo con una acción deleteTodo.

{{view Ember.Checkbox checkedBinding="isDone"}}

{{view App.TodoItemEditView valueBinding="title" class="required" disabledBinding="isDone"}}

<a href="#" {{action "deleteTodo" on="click" target="view"}}>X</a>

La clase HtmlHelperExtensions, definida en Controllers/HtmlHelperExtensions.cs, define una función auxiliar para almacenar en caché e insertar archivos de plantilla cuando debug se establece en true en el archivo Web.config. Se llama a esta función desde el archivo de vista de ASP.NET MVC definido en Views/Home/App.cshtml:

@if (HttpContext.Current.IsDebuggingEnabled)
{
    @Html.RenderEmber()
}
else
{
    @Scripts.Render("~/bundles/templates")
}

Llamada sin argumentos, la función representa todos los archivos de plantilla de la carpeta Plantillas. También puede especificar una subcarpeta o un archivo de plantilla específico.

Cuando debug es false en Web.config, la aplicación incluye el elemento de agrupación "~/bundles/templates". Este elemento de agrupación se agrega en BundleConfig.cs, mediante la biblioteca del compilador de Handlebars:

if (!HttpContext.Current.IsDebuggingEnabled)
{
    bundles.Add(new Bundle("~/bundles/templates", 
        new EmberHandlebarsBundleTransform()).Include(
            "~/scripts/app/templates/*.hbs"
        ));
}