1
votes

In the current version of jQuery Mobile it seems to be necessary to keep all data-role="page" elements on one level (at least when one wants to establish links between them). Since I am using knockout to dynamically produce pages, I have the requirement to bind virtual elements directly, e.g. in

<div data-role="page" id="page1"><h1 data-bind="text: name"></h1></div>
<!-- ko text: name --><!-- /ko -->

I want to bind one model A to page1 and one model B to the virtual element (which is a template: foreach binding in the real application). More detailed fiddle: http://jsfiddle.net/timvdh/t3Cyd/3/

Is this doable somehow?

1
I don't know about KO, but you can add listeners on pagecreate of each page separately. In case you want to do something when pages are shown (pageContainer events) it's not possible UNLESS you place each page in a different pageContainer. This way, each page will act as an individual page with its own bindings. - Omar
You might checkout the knockout with binding knockoutjs.com/documentation/with-binding.html - John
@Omar The documentation says (api.jquerymobile.com/pagecontainer) that the pagecontainer currently is a singleton, I therefore didn't bother using more than one container per html page. Is it possible to use more than one pagecontainer in 1.4.2? - TvdH
You can use, check this comment github.com/jquery/jquery-mobile/issues/… - Omar
@Omar ...and I should learn jQM ;) Knockout is great, but it does not play nicely with jQM. Since it is the only JavaScript MVC (MVVM actually) framework I have used, I cannot say much about the competition like Angular JS (I don't like that its functionality overlaps with jQuery) or Ember or Backbone (to name a few). - TvdH

1 Answers

0
votes

With the limited information I would say you have 3 options:

(1) Wrap your virtual element in another virtual element or div and use the with binding.

<!-- ko with: modelForPage2 -->
    <!-- ko text: name --><!-- /ko -->
<!-- /ko -->

(2) Use the template binding in the virtual element and use the data property to supply a new context.

<!-- ko template: { name: 'page2_template', data: modelForPage2 } --><!-- /ko -->

(3) Create your own custom binding that supports virtual elements and apply bindings to descendants. This is just an example to lead you in the right direction:

ko.bindingHandlers.bindModel = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) {
        var newContext = new ModelA();
        ko.applyBindingsToDescendants(newContext, element);
        return { controlsDescendantBindings: true };
    }
};
ko.virtualElements.allowedBindings.bindModel = true;