2012-02-09 13 views
7

Lo que estoy haciendo:Backbone.js + KendoUI - enrutamiento, Vistas, y la estructuración de la red

Estoy creando una aplicación de ejemplo que muestra cómo incorporar Kendo interfaz de usuario controla con Backbone.js utilizando rieles 3 como un servidor JSON.

Hasta ahora, tengo Vistas de Backbone que están administrando plantillas en un archivo erb y un Enrutador de Backbone que está administrando las Vistas en sí mismas, dependiendo de los enlaces en los que se hace clic.

Cuando esto termine, quiero que todo esté disponible como un tutorial para ayudar a la gente que quiere entrar en Backbone - y KendoUI (que también es bastante genial).

El problema:

La rejilla Kendo no está prestando a través de la vista Usuarios método Render - a pesar de que es la plantilla contenedor es.

En este momento, tengo que representar la cuadrícula desde el método Usuarios del enrutador, después de que el enrutador haya representado la vista del usuario.

enter image description here

Parece extraño que hace que la plantilla, pero la red no lo hace - o me estoy perdiendo algo?

Tal vez será más fácil de entender una vez que vea el código:

index.html.erb

<h1>Kendo Grid Test</h1> 

<div id="nav"></div> 


<div id="container"> 

<!-- The templates below will be placed here dynamically --> 

</div> 

<!-- TEMPLATES --> 
<script type="text/template" id="users-grid-template"> 
    <p>Users Grid Template</p> 

    <div id="users-grid"></div> 


</script> 

<script type="text/template" id="posts-grid-template"> 
    <div id="posts-grid"></div> 
</script> 



<script type="text/template" id="nav-template"> 
    <div> 
    <ul id="nav_container"> 
     <li><a href="#users">Users</a></li> 
     <li><a href="#posts">Posts</a></li> 
    </ul> 
    </div> 
</script> 

Backbone Usuarios Ver

window.UsersView = Backbone.View.extend({ 

      initialize: function() {         
       _.bindAll(this, "render"); 
       this.usersGrid = _.template($("#users-grid-template").html()); 
       this.render().el;     
      }, 

      render: function() {     
       $(this.el).html(this.usersGrid).fadeIn(); 
       return this; 
      } 

     }); 

Backbone Enrutador

window.AppRouter = Backbone.Router.extend({ 

     routes: { 
      'users': 'users', 
      'posts': 'posts' 

     }, 

     initialize: function() {    
      this.usersView = new UsersView; 
     },  

     posts: function() { 
      var container = $("#container"); 
      container.empty(); 
     },  


     users: function() { 

      var container = $("#container"); 
      container.empty();   

      container.append(this.usersView.render().el); 

      var UsersData = new kendo.data.DataSource({ 
        transport: { 
         read: { 
          url: "/users", 
          dataType: "json" 
         } 
        } 
       });    

       var grid = $("#users-grid").kendoGrid({ 

        dataSource: UsersData, 

        columns: [ 
        { 
         field: "first_name", 
         title: "First Name" 
        }, 
        { 
         field: "last_name", 
         title: "Last Name", 

        }] 
       }); 

       container.append(grid);    
     }   
    }); 



    window.App = new AppRouter(); 
    Backbone.history.start(); 

Como se puede ver, la red de Kendo interfaz de usuario se genera dinámicamente y se coloca en el <div id="users-grid"></div> de los "usuarios de la red en la plantilla". Pero, tengo que hacer un método de 'agregar' por separado para que la cuadrícula entre en la plantilla. Esto parece innecesario.

Parece como si tuviera que ser capaz de colocar todo esto ...

enter image description here

... interior de la UsersView método Render - sin tener que utilizar el método de agregación. Pero no puedo hacer que eso funcione.

¿Alguna sugerencia sobre cómo estructurar esto? ¿O si mi código actual está estructurado correctamente?

Consejo muy apreciado!


EDITAR - simplificado Solution (gracias a Derick)

me di cuenta de que yo era complicar esto. Intenté usar Backbone para hacer lo que Kendo ya estaba haciendo: administrar su grid y su fuente de datos.

Dado que Backbone es tan modular, y todo lo que realmente necesitaba por el momento era su enrutador, eliminé todas las vistas, excepto la vista de navegación, y acabo de usar el enrutador y dejé que Kendo hiciera lo suyo.

Creo que la solución es mucho más simple y fácil de administrar el código. (al menos para mí)

$(document).ready(function(){ 


     window.Navigation = Backbone.View.extend({ 
     el: $("#nav"),   

     initialize: function() {    
      _.bindAll(this, "render"); 
      this.nav = $("#nav-template").html(); 
      this.render().el; 
     }, 

     render: function() { 
      $(this.el).html(this.nav); 
      return this; 
     } 



     }); 

    window.nav = new Navigation; 

    window.AppRouter = Backbone.Router.extend({ 

     routes: { 
      'users': 'users', 
      'posts': 'posts' 

     }, 

     initialize: function() {    
      var container = $("#container"); 
      //container.html("#users-grid"); 
     },  

     posts: function() { 
      var container = $("#container"); 
      container.empty(); 
     },  


     users: function() { 

      var container = $("#container"); 
      usersTemplate = _.template($("#users-grid-template").html()); 
      container.empty(); 
      container.html(usersTemplate); 

      var UsersData = new kendo.data.DataSource({ 
        transport: { 
         read: { 
          url: "/users", 
          dataType: "json" 
         } 
        } 
       });    

       $("#users-grid").kendoGrid({ 

        dataSource: UsersData, 

        columns: [ 
        { 
         field: "first_name", 
         title: "First Name" 
        }, 
        { 
         field: "last_name", 
         title: "Last Name", 

        }] 
       });        
     }   
    }); 

    window.App = new AppRouter(); 
    Backbone.history.start(); 




// Closing jquery tag  
}); 

Esperemos que alguien lo encuentre útil.

Siguiente paso: aplicar CRUD a esto.

Respuesta

8

el problema se debe a la falta de alcance del selector al intentar llamar al .kendoGrid. Rellenar su contenido en el el.html(...) no asocia el el de su vista al DOM, por lo que una llamada al $("#users-grid") no tiene nada que encontrar, aún.

Puede seguir llamando kendoGrid en el de la vista, pero hay que alcance su "# usuario de la red" de selección a la vista de hacerlo:

Backbone.View.extend({ 

    render: function(){ 
    this.$el.html(this.usersGrid); 

    this.$("#user-grid").kendoGrid({ 
     // kendo grid options here 
    }); 
    } 

}); 

llamando this.$ como una función en un punto de vista es un método de acceso directo en la vista, para usar el el como contexto para su selector de jquery. Es lo mismo que llamar a this.$el.find("#users-grid")

FWIW: Estoy usando mucho Kendo en estos días y me encanta con Backbone. Todavía no me he topado con un control Kendo que necesita un manejo especial fuera del método de renderización de una vista.

+0

Hola Derick, muchas gracias por echar un vistazo a mi problema. Todavía tengo algunos problemas, pero intenté incorporar los cambios que sugirió e hice una edición superior para que pueda ver el código completo. Quizás puedas decir dónde estoy yendo mal. Siento que estoy al borde de entender esto, pero aún me falta algo fundamental. Estuve dando vueltas con esto por unas horas y ahora mi mente ha decidido tomar vacaciones :) – PhillipKregg

+0

en el nuevo código, está renderizando la vista dos veces: una en el método de inicialización de la vista y otra en el enrutador . deshacerse de una de las llamadas a '.render()' ... lo eliminaría del método de inicialización de la vista, personalmente. que puede estar causando problemas restantes –

+0

Hola, cuando dijiste que estoy reproduciendo la vista dos veces, pensé: estoy tratando de hacer que Backbone administre vistas, pero la grilla de Kendo y el origen de datos ya están haciendo eso para yo. Intento recrear el trabajo con Backbone cuando no es necesario, al menos por lo que estoy haciendo ahora. Guardaré las vistas para cuando necesite más controles personalizados más tarde. ¡Gracias de nuevo! – PhillipKregg

Cuestiones relacionadas