twitter bootstrap - Knockout conditional binding -
ok, i've been been building spa application, , looking have different layout depending on whether site viewed on phone or laptop.
if using bootstrap, provides conditional hiding/showing of css classes, , while works nicely does, doesn't work when layout changes beyond point. alternative layout, wind needing put 2 sets of divs on 1 page, use conditional javascript code wipe out inner html of target div. prevents charts being populated parts of page never seen.
var setviewscape = function () { var l = $(".positiondetails").length; if (l == 0) { settimeout(function() { setviewscape(); }, 10); } else { if (window.innerwidth <= 899) { $(".landscape").html(""); $(".phonescape").css("visibility", "visible"); } else { $(".phonescape").html(""); $(".landscape").css("visibility", "visible"); } } };
so far good, except when observe happening on page knockout, second set of knockout tags still being bound to. tried adding ko conditional bind controls intending show:
<div id="content" class="main"> <div class="row landscape"> <!--ko if: $(window.innerwidth > 899) --> <div class="col-8 col-lg-8"> <!--ko compose: {view: 'positions/list'} --><!--/ko--> </div> <div class="col-lg-4 col-4 " > <!--ko compose: {view: 'shared/summarygraph'} --><!--/ko--> <!--ko compose: {view: 'shared/membersummary'} --><!--/ko--> <!--ko compose: {view: 'shared/membercalendar'} --><!--/ko--> <!--ko compose: {view: 'shared/membertwitter'} --><!--/ko--> <div data-bind="visible: advert() != null && advert().length > 0" id="advert" class="img-rounded container-fluid" style="min-width: 120px; min-height: 680px; height: inherit; margin-bottom: 30px; background-color:whitesmoke "> <h4>advert</h4> </div> </div> <!--/ko--> </div> <div class="row phonescape" style="padding-left: 15px; padding-top: 15px;"> <!--ko if: $(window.innerwidth <= 899) --> <div class="col-sm-12"> <!--ko compose: {view: 'shared/membersummary'} --><!--/ko--> <!--ko compose: {view: 'shared/sagasummarygraph'} --><!--/ko--> <!--ko compose: {view: 'positions/list'} --><!--/ko--> </div> <!--/ko--> </div> </div>
but when observe debug info see ["binding", "views/positions/list", ko.bindingcontext] ["binding", "views/positions/list", ko.bindingcontext]
["binding", "views/shared/membersummary", ko.bindingcontext] ["binding", "views/shared/membersummary", ko.bindingcontext]
["binding", "views/shared/summarygraph", ko.bindingcontext] ["binding", "views/shared/summarygraph", ko.bindingcontext]
i has got performance hit.
what i'm trying bind either 'phonescape' or 'landscape' mode , remove must performance hit. idea how this?
recently, used observable extension extension updates observable based on whether media query hit or not. define observable like:
this.large = ko.observable().matchmedia("(min-width: 800px)");
then, can bind areas of page against "large" ( if: large
) prevent areas being bound don't want.
the code bit naive in supports min/max width queries against px based measurements in older browsers.
here using:
//small extension update observable based on media query (function() { var self = ko.observable.fn.matchmedia = function(query) { self["matchmedia" in window ? "syncwithmatchmedia" : "syncwithresize"](this, query); return this; }; self.syncwithmatchmedia = function(observable, mediaquery) { var query = window.matchmedia(mediaquery); observable(query.matches); query.addlistener(function(query) { observable(query.matches); }); }; self.syncwithresize = function(observable, mediaquery) { var pieces = mediaquery.split(":"), ismax = pieces[0].indexof("max") > -1, value = pieces[1].replace(")", "").replace("px",""), //just works px currentwidth; var matcher = function() { var width = document.outerwidth || document.body.clientwidth; //see if changed if (width !== currentwidth) { currentwidth = width; observable(ismax ? value > width : value < width); } } matcher(); ko.utils.registereventhandler(window, "resize", matcher); }; })();
it falls use resize
event, if matchmedia
api not supported browser.
here sample: http://jsfiddle.net/rniemeyer/7s2hz/
Comments
Post a Comment