Backbone.js + KendoUI - routing, viewing and structuring using a grid

What am I doing:

I am creating an example application that shows how to enable Kendo UI controls using Backbone.js using Rails 3 as a JSON server.

So far, I have Backbone Views that control the templates in the erb file and a Backbone Router that controls the views themselves - depending on the links that were clicked.

When it's done, I want to make it all available as a tutorial to help people who want to get into Backbone - and KendoUI (which is also pretty cool).

Problem:

The Kendo mesh is not executed through the User Viewer rendering method - even though it is a container template.

Right now, I need to display the grid from the "Users" method of the router - after the router has displayed the user view.

enter image description here

It seems strange that the template renders, but the grid is not working - or am I missing something?

Perhaps it will be easier for you to understand as soon as you see the code:

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> 

Overview of Backbone Network Users

 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; } }); 

Trunk router

 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(); 

As you can see, the Kendo user interface grid is dynamically generated and placed in the <div id="users-grid"></div> "user-grid-template" template. But I have to make a separate add method to get the grid in the template. This seems unnecessary.

I think I should be able to post it all ...

enter image description here

... inside the UserView Render method - without using the append method. But I can't get this to work.

Any suggestions on how to structure this? Or is my current code structured correctly?

Tips are greatly appreciated!


EDIT - simplified solution (thanks Derick)

I realized that I am over complicating this. I tried to use Backbone to do what Kendo already did - managing the grid and data source.

Since Backbone is so modular, and all I really needed at the moment was Router, I deleted all views - except the navigation view - and just used Router and gave Kendo my job.

I think the solution is much simpler and simpler in code management. (at least for me)

 $(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 }); 

Hope someone finds this helpful.

The next step is to apply CRUD to this.

+7
source share
1 answer

The problem is due to the lack of definition of the scope of the selector when trying to call .kendoGrid . Overlapping your content with el.html(...) does not bind your el view to the DOM, so calling $("#users-grid") has not yet been found.

You can still call kendoGrid in the el view, but for this you must specify your selector "# user-grid" for the view:

 Backbone.View.extend({ render: function(){ this.$el.html(this.usersGrid); this.$("#user-grid").kendoGrid({ // kendo grid options here }); } }); 

calling this.$ as a function in the view is a shortcut method in the view to use el as the context for your jquery selector. This is the same as calling this.$el.find("#users-grid")

FWIW: These days I use Kendo a lot and love it with Backbone. I have not yet encountered a Kendo control that needs some real special processing outside of the visualization method.

+8
source

All Articles