frigon
frigon

Reputation: 5129

Manually load kendo mobile view

I'm working on a Kendo Mobile project with a number of:

  1. Kendo Views (external to root html)
  2. Modal Views (in the root html).

The external files load on demand and everything works fine. But i'd like to have the same load on demand behavior for some of the modal views, because the root/based html file is becoming too large and not manageable.

Is there a way to either:

  1. Store a modal view in an external file? If so is it possible to load via javascript syntax (app.navigate()) rather than the declarative syntax (href='externalmodal').
  2. Manually pre-load an external view without navigating to it first.

Upvotes: 1

Views: 504

Answers (1)

robocat
robocat

Reputation: 5443

This code lets you manually create a view:

var viewUrl = 'blahblahblah';
var element = $.parseHTML('<div data-role=view>test</div>')[0];
element.style.display = 'none';
$(document.body).append(element);
var options = $.extend({}, kendo.parseOptions(element, kendo.mobile.ui.View.fn.options));
var view = new kendo.mobile.ui.View(element, options);
view.element[0].setAttribute('data-url', viewUrl);
kendo.mobile.application.navigate(viewUrl, '');

Depending on what features you use, you may need to instead use code similar that that used for ModalView below so that Kendo creates the subclass (changes: substitute View for ModalView, substitute view for modalview, add data-url, remove call to show(), maybe check that view not already created by checking for element with matching data-url). We haven't tested setting roles.view this way, but we did something similar while testing this stuff out and it worked.

Don't try settings the options - Kendo got confused (at least trying to set useNativeScrolling didn't work, also don't try setting the options object on the subclass unless you really know what you are doing).

Caveat: This was using browserHistory:false (which disables routing) when the kendo.mobile.Application was created. The technique should still work when using browser history if you use a valid url fragment (same as would be created by Kendo for the pushstate/hashchange url).

This is a also way to cleanly subclass kendo.mobile.ui.View that works well - although you must still use data-role=view even though your subclass is a "different" component. Note that you can't just use you cant use your own subclassed component with its own name like role=myview to subclass a view because there are hard-coded checks specifically for data-role=view in the kendo codebase. Same if you wish to subclass: layout modalview drawer splitview page (amongst other hard-coded kendo ui component names - search kendo code for kendo.roleSelector - ugly). e.g.

MyView = kendo.mobile.ui.View.extend({
    init: function(element, options) {
        kendo.mobile.ui.View.prototype.init.apply(this, arguments);
        ...

var myView = new MyView('<div data-role=view>test</div>');

Why it works: The relevant function in the Kendo source code is _findViewElement which does element = this.container.children("[" + attr("url") + "='" + urlPath + "']"); to see if the view already exists for a url, before creating a new one. A unique init function is always required as it ends up being the constructor function.

If you want to subclass a modalview, you need to do something different due to the way kendo works:

var MyModalView = kendo.mobile.ui.ModalView.extend({
  html: '<div data-role=modalview style="width:90%;display:none;">Foobar</div>',
  init: function() {
    kendo.mobile.ui.ModalView.prototype.init.apply(this, arguments); 
  }
});

function makeModalView() {
  $(document.body).append($.parseHTML(MyModalView.prototype.html));
  var roles = $.extend({}, kendo.mobile.ui.roles);
  roles.modalview = MyModalView;
  var modalView = kendo.initWidget($(element), {}, roles);
  modalView.open();
  return modalView;
}

Upvotes: 1

Related Questions