I am working on Android with jQuery Mobile using Phonegap, using Knockout to load data.
I get the data in order and upload it to the html page according to the foreach data binding that I have in the tags.
When I want to update the data, it just does not do this. It returns only html without bound data, or a dom My applyBinding exception exception exception occurs inside the pagecreate event on the page.
I posted a simple example describing the problem on my SkyDrive - http://sdrv.ms/LpUdLt This is a public example reproducing the problem. viewmodel contains an array containing the array. illuminated by random values. trying to reload a page in jQuery mobile with reloading changepage with new data by pressing the navbar button with dom dom error. I donโt agree that I should not create a virtual machine instance for each pagecreate, I just canโt find a way to implement it so that the data is rewritten in html.
//indexPage.js var wAViewModelInst ; var viewPageIndexContent; $('#pageIndex').live('pagecreate', function (event) { viewPageIndexContent = document.getElementById("pageIndexContent"); wAViewModelInst = new WAViewModel(true); ko.applyBindings(wAViewModelInst, viewPageIndexContent); waHeaderVM.refreshContentData = function () { // wAViewModelInst.updateRowList(); // ko.cleanNode(viewPageIndexContent); // viewPageIndexContent = document.getElementById("pageIndexContent"); //wAViewModelInst = new WAViewModel(true); //ko.applyBindings(wAViewModelInst, viewPageIndexContent); $.mobile.changePage("index.html", { allowSamePageTransition: true, reloadPage: true }); $.mobile.hidePageLoadingMsg(); } } //WAViewModel self.WARowList = ko.observableArray(); self.updateRowList = function () { self.WARowList(self.GetWA()); } //tried the exteding //ko.observableArray.fn.WARowListUpdate = function () { // //create a sub-observable // this.hasItems = ko.observable(); // //update it when the observableArray is updated // this.subscribe(function (newValue) { // this.hasItems(newValue && newValue.length ? true : false); // }, this); // //trigger change to initialize the value // this.valueHasMutated(); // //support chaining by returning the array // return this; //};
Is there a way to update html after the first rendering?
adding html code:
<div id="pageIndex" data-role="page" data-transition="flip" data-theme="e" data-dom-cache="true"> <div id="indexHeader" data-role="header" data-theme="e"> <div data-role="navbar" data-iconpos="right"> <ul> <li><a href="login.html" data-role="tab" data-icon="back" data-bind="click: loadingHandler" class="brighter-text">ืืืจื</a></li> <li><a href="#" data-role="tab" data-icon="refresh" data-bind ="click: refreshContentData" >ืจืขื ื</a></li> <li><a href="researchEvent.html" data-role="tab" data-icon="check" id="navBarResearchEventPage" data-bind="click: loadResearchEvent" class="brighter-text">ืืืฆืืข ืืงืจ</a></li> <li><a href="#" data-role="tab" data-icon="grid" class="ui-btn-active brighter-text"> ืกืืืืจ ืขืืืื</a></li> </ul> </div> </div> <div id="pageIndexContent" data-role="content" data-theme="e" style="padding-bottom: 52px; height: 570px;"> <h2 data-bind="text:Title" class="brighter-text" style="font-size:22pt;"> </h2> <div data-bind="foreach: WARowList" style="width: 99%; text-align: center"> <div> <table style="float: right; width: 20%; height: 60px;" cellpadding="0" cellspacing="0"> <tr data-bind="visible : FirstRow " style="height: 31px;"> <th class="AlignedHeader"> <label> ืฉืขื / ืฉืืืื</label> </th> </tr> <tr data-bind="style: { backgroundColor: Odd() ? '#8CC63F' : '#AFC493' }"> <td style="width: 20%;" data-bind="style: { backgroundColor: IsNew() ? 'yellow' : 'transparent' }"> <input type="button" data-bind="click: ShowSampleDetails, value: ShilutTime , jQueryButtonUIEnableDisable:$data" data-icon="plus" data-iconpos="right"/> </td> </tr> </table> <table style="height: 60px; width: 80%; background-color: #8CC63F;" data-bind="style: { backgroundColor: Odd() ? '#8CC63F' : '#AFC493' }" cellpadding="0" cellspacing="0"> <thead data-bind="if : FirstRow"> <tr data-bind="foreach: CellList"> <th class="AlignedHeader"> <label data-bind="text: Date"> </label> </th> </tr> </thead> <tbody> <tr data-bind="foreach: CellList"> <td style="width: 11.5%;"> <div data-bind="visible:IsPopulated "> <div data-bind="visible: HasDrivers"> <input type="button" data-role="button" data-bind="click: ShowBusDriverList.bind($data , $root) , jQueryButtonUIEnableDisable: $data " data-icon="search" data-iconpos="right" value="ื ืืืื" class="brighter-text" /> </div> <div data-bind="visible: !HasDrivers()"> <input type="button" data-role="button" id="btnNoDriver" disabled="disabled" data-icon="info" data-iconpos="right" value="ืืื ื ืื" class="brighter-text" /> </div> </div> <div data-bind="visible: !IsPopulated"> </div> </td> </tr> </tbody> </table> </div>
etc.
the GetWA function returns an observable array of the warow list. it works the first time the problem reengines the dom object. The dom element is dirty ko and fails.
I tried Luffy's answer:
var lVM = new loginViewModel(); var footerViewModelLogin = { IsOnline: ko.observable(globalContext.Network()), IsSync: ko.observable(globalContext.Sync()) }; $('#login').live('pagecreate', function (event) { viewLoginContent = document.getElementById("loginContent"); ko.applyBindingsToNode(viewLoginContent, lVM); viewLoginFooter= document.getElementById("footerLogin"); ko.applyBindingsToNode(viewLoginFooter, footerViewModelLogin); }); $('#login').live('pagehide', function (event, ui) { $.mobile.hidePageLoadingMsg(); }); function loginViewModel() { var self = this; try { self.userName = ko.observable(""); self.password = ko.observable(""); self.message = ko.observable(""); self.CleanGlobalContext = function () { ... }; self.Validate = function () { ... }; } catch (e) { if (IsDebug) alert("GlobalContext.prototype.SetMapOverlay " + e.message); if (typeof (console) != 'undefined' && console) console.log("GlobalContext.prototype.SetMapOverlay " + e.message); } } ko.applyBindings(lVM); ko.applyBindings(footerViewModelLogin);
Knockout fails without snapping an item previously defined for snapping.