Kendo UI Web: Remote Views And Separate HTML Files

By February 10, 2014JavaScript

When working with Kendo’s SPA implementation, you will soon realize that you can only create views out of existing elements on the page or feeding it raw HTML. What about remote views? Unfortunately, only Kendo UI Mobile gets to have remote views. In this post, I will show you how to extend Kendo UI Web’s kendo.View to give it remote view capabilities just like mobile!

//EXTEND KENDO VIEW TO HANDLE REMOTE VIEWS
var extendedView = kendo.View.extend({
    promise: null,
     
    init: function(element, options) {
        var me = this;
         
        //DETERMINE IF ELEMENT IS URL FOR REMOTE RETRIEVAL
        if (_.isString(element) && !/<[a-z][\s\S]*>/i.test(element)) {
            //GET REMOTE INITIAL VIEW
            this.promise = $.get(element).done(function (html) {
                //STORE REMOTE VIEW IN ELEMENT PARAM
                element = html;
                 
                //CALL BASE CONSTRUCTOR WITH NEW ELEMENT
                kendo.View.fn.init.call(me, element, options);
            });
        } else {
            //NOT REMOTE VIEW SO PROCEED AS USUAL
            kendo.View.fn.init.call(this, element, options);
        }
    },
     
    render: function (container) {
        var me = this;
         
        //HANDLE AJAX REMOTE VIEW IF APPLICABLE
        if (this.promise) {
            this.promise.then(function () {
                kendo.View.fn.render.call(me, container);
            });
        } else {    
            //NOT REMOTE VIEW SO PROCEED AS USUAL
            kendo.View.fn.render.call(this, container);
        }
    }
});

Now I can use it like this:

var view = new extendedView('/echo/html/', {
    model: kendo.observable({
        sourceThings: [
            'KendoUI remote view loaded!',
            'Test item 1',
            'Test item 2',
            'Test item 3'
        ]
    })
});
 
view.render('#main');

In the extended view implementation, I am first checking to see if the “element” parameter is a remote view path. I do this using duck-typing (if it walks like a duck…it must be a duck) by checking if it is a string and not an HTML element, then proceed on to check that it is not raw HTML either. If those criteria pass, then I assume it’s a URL path to a remote view. Not such a bad assumption, unless Kendo allows you to specify a selector as the element parameter one day. I could explicitly add a new boolean property called remoteView and act accordingly, but I think the RegEx can be improved from here instead (any RegEx experts please chime in :).

Once we determine that the request is for a remote view, I start an AJAX call to get the remote view. When the remote view is received, I stuff that raw HTML into the “element” parameter and let it proceed to initialize as normal. This works because, remember, the element parameter is allowed to be raw HTML.

Great… but wait! If you call “render” you will get an error because it will probably start before the AJAX completes. How do you solve this riddle? During the initialize where we requested the remote view, store the AJAX promise into a new property of the view called anything like “promise“. Now we can override the “render” function and wait for that promise to finish before letting it render as usual. Now it works!

Check it out on jsFiddle. Note it’s using a simulated AJAX call to make it work in jsFiddle with a delay of 3 seconds. Alas, Kendo UI Web SPA with remote views.

Happy Coding!!

The following two tabs change content below.