2013-03-04 3 views
5

Ok, quindi questo sta cominciando a farmi impazzire. Ho cercato e cercato per diverse ore, e ogni singola soluzione non funziona per me. Quindi sì, questa domanda potrebbe essere ridondante, ma non posso per la vita di me ottenere soluzioni per funzionare.jQuery Mobile e Knockout.js template, lo stile non è applicato

Ho un gruppo di checkboxes generate da un template jquery che è database via knockout.js. Tuttavia, si presenta unstyled. Afaik, è qualcosa su jquery mobile fa lo styling prima di knockout rende il modello, quindi finisce senza eccessi. Ho provato numerosi metodi inutilmente, quindi spero che qualcuno qui possa vedere cosa sto facendo male.

(sto usando jQuery Mobile 1.2.0, jQuery 1.8.2 e 2.2.1 knockout)

Questo è lo script:

<script type="text/javascript">  


jQuery.support.cors = true; 

var dataFromServer = "";  
// create ViewModel with Geography, name, email, frequency and jobtype 
var ViewModel = { 
    email: ko.observable(""), 
    geographyList: ["Hovedstaden","Sjælland","Fyn + øer","Nordjylland","Midtjylland","Sønderjylland" ], 
    selectedGeographies: ko.observableArray(dataFromServer.split(",")), 
    frequencySelection: ko.observable("frequency"), 
    jobTypes: ["Kontor (administration, sekretær og reception)","Jura","HR, Ledelse, strategi og udvikling","Marketing, kommunikation og PR","Handel og service (butik, service, værtinde og piccoline)","IT","Grafik og design","Lager, chauffør, bud mv.","Økonomi, regnskab og finans","Kundeservice, telefoninterview, salg og telemarketing","Sprog","Øvrige jobtyper"], 
    selectedJobTypes: ko.observableArray(dataFromServer.split(",")), 
    workTimes: ["Fulltid","Deltid"], 
    selectedWorkTimes: ko.observableArray(dataFromServer.split(",")) 
}; 

// function for returning checkbox selection as comma separated list 
ViewModel.selectedJobTypesDelimited = ko.dependentObservable(function() { 
    return this.selectedJobTypes().join(","); 
}, ViewModel); 

var API_URL = "/webapi/api/Subscriptions/"; 

// function used for parsing json message before sent 
function omitKeys(obj, keys) { 
    var dup = {}; 
    var key; 
    for (key in obj) { 
    if (obj.hasOwnProperty(key)) { 
     if (keys.indexOf(key) === -1) { 
     dup[key] = obj[key]; 
     } 
    } 
    } 
    return dup; 
} 

//Function called for inserting new subscription record 
function subscribe() { 
    if($("#jobmailForm").valid()=== true){ 
    //window.alert("add subscriptiooncalled"); 
    var mySubscription = ko.toJS(ViewModel); 
    //var json = JSON.stringify(mySubscription); 
    var jsonSmall = JSON.stringify(omitKeys(mySubscription, ['geographyList','jobTypes','selectedJobTypesDelimited','workTimes'])); 
    //window.alert(jsonSmall); 
    $.ajax({ 
     url: API_URL, 
     cache: false, 
     type: 'POST', 
     contentType: 'application/json', 
     data: jsonSmall, 
     success: function (data) { 
      window.alert("success"); 

     }, 
     error: function (error) { 
      window.alert("ERROR STATUS: " + error.status + " STATUS TEXT: " + error.statusText); 

     } 
    }); 
    } 
} 

function initializeViewModel() { 
    // Get the post from the API  
    var self = this; //Declare observable which will be bind with UI 
    // Activates knockout.js 
    ko.applyBindings(ViewModel); 
} 

// Handle the DOM Ready (Finished Rendering the DOM) 
$("#jobmail").live("pageinit", function() { 
    initializeViewModel(); 
    $('#jobmailDiv').trigger('updatelayout'); 
}); 


</script> 
    <script id="geographyTmpl" type="text/html"> 
    <input type="checkbox" data-role="none" data-bind="attr: { value: $data }, attr: { id: $data }, checked: $root.selectedGeographies" /> 
    <label data-bind="attr: { for: $data }"><span data-bind="text: $data"></span></label> 
    </script> 
    <script id="jobTypeTmpl" type="text/html"> 
    <label><input type="checkbox" data-role="none" data-bind="attr: { value: $data }, checked: $root.selectedJobTypes" /><span data-bind="text: $data"></span></label> 
    </script> 

nota, "Jobmail" è la pagina circostante" "elemento div, non mostrato qui. E questo è il markup:

<div data-role="content"> 
<umbraco:Item field="bodyText" runat="server"></umbraco:Item> 
<form id="jobmailForm" runat="server" data-ajax="false"> 
    <div id="jobmailDiv"> 
    <p> 
    <label for="email">Email</label> 
    <input type="text" name="email" id="email" class="required email" data-bind="'value': email" /> 
    </p> 

    <fieldset data-role="controlgroup" data-mini="true" data-bind="template: { name: 'geographyTmpl', foreach: geographyList, templateOptions: { selections: selectedGeographies } }"> 
    <input type="checkbox" id="lol" /> 
    <label for="lol">fkfkufk</label> 
    </fieldset> 
    <fieldset data-role="controlgroup" data-mini="true"> 
    <p data-bind="template: { name: 'jobTypeTmpl', foreach: jobTypes, templateOptions: { selections: selectedJobTypes } }"></p> 
    </fieldset> 

    <fieldset data-role="controlgroup" data-mini="true"> 
    <input type="radio" id="frequency5" name="frequency" value="5" data-bind="checked: frequencySelection" /><label for="frequency5">Højst 5 gange om ugen</label> 
    <input type="radio" id="frequency3" name="frequency" value="3" data-bind="checked: frequencySelection" /><label for="frequency3">Højst 3 gange om ugen</label> 
    <input type="radio" id="frequency1" name="frequency" value="1" data-bind="checked: frequencySelection" /><label for="frequency1">Højst 1 gang om ugen</label> 
    </fieldset> 

    <p> 
    <input type="button" value="Tilmeld" class="nice small radius action button" onClick="subscribe();"> 
    </p> 

    <a href="{locallink:1733}" data-role="button" data-icon="back" data-inline="true" data-direction="reverse">Tilbage</a> 
</div> 
</form> 

Metodo alternativo di invocare il restyling (non funziona neanche):

$(document).on('pagebeforeshow', '#jobmail', function(){  
// Get the post from the API  
    var self = this; //Declare observable which will be bind with UI 
    // Activates knockout.js 
    ko.applyBindings(ViewModel); 
}); 
// Handle the DOM Ready (Finished Rendering the DOM) 
$("#jobmail").live("pageinit", function() { 
    $('#jobmail').trigger('pagecreate'); 
}); 

risposta

3

Ogni contenuti generati dinamicamente jQuery Mobile deve essere rafforzata manualmente.

può essere fatto in diversi modi, ma uno più comune può essere fatto attraverso la funzione jQuery Mobile.trigger(.

Esempio:

  • solo migliorare il contenuto della pagina

    $('#page-id').trigger('create'); 
    
  • Migliorare pagina intera (intestazione + contenuti + piè di pagina):

    $('#page-id').trigger('pagecreate'); 
    

Se vuoi saperne di più su questo argomento dai un'occhiata al mio altro ARTICLE, per essere più trasparente è il mio blog personale. O lo trovi HERE.

+0

Grazie per la risposta, questo piccolo articolo è di grande aiuto per riferimento futuro. Ho provato il tuo suggerimento, e ho una leggera variazione nel mio codice nel mio post originale, né funziona. Ho provato a inserire il codice che rende la rilegatura a strappo nel documento su pagebeforeshow e il restyling su pageinit, sembra ragionevole, ma non funziona. Hai un suggerimento su quando nel mio codice dovrebbe essere attivato? –

+0

Dovrebbe essere posizionato dopo che tutte le caselle di controllo sono state generate. Se lo fai all'interno di un ciclo, il trigger ('create') deve andare dopo il ciclo. E non farlo per ogni iterazione del ciclo, rallenterà la generazione della pagina. Quindi fallo una sola volta dopo che tutto il contenuto dinamico è stato generato. – Gajotres

+0

Ma questo è quello che ho cercato di fare, senza fortuna. Sono completamente in perdita. –

5

Utilizzare un'associazione personalizzata (Knockout) per attivare jQuery Mobile su migliorare il contenuto creato dinamicamente prodotto da Knockout.

Ecco un semplice personalizzato vincolante:

ko.bindingHandlers.jqmEnhance = { 
    update: function (element, valueAccessor) { 
     // Get jQuery Mobile to enhance elements within this element 
     $(element).trigger("create"); 
    } 
}; 

Utilizzare vincolante nel codice HTML in questo modo l'usanza, dove myValue è la parte del tuo modello di vista che cambia, innescando il contenuto dinamico da inserire nel DOM :

<div data-bind="jqmEnhance: myValue"> 
     <span data-bind="text: someProperty"></span> 
     <a href="#some-id" data-role="button">My Button</a> 
     <input type="radio" id="my-id" name="my-name" value="1" data-bind="checked: someOtherProperty" /><label for="my-id">My Label</label> 
    </div> 

nel mio caso, myValue faceva parte di un'espressione in un if vincolante, che farebbe scattare i contenuti da aggiungere al DOM.

<!-- ko if: myValue --> 
    <span data-bind="jqmEnhance: myValue"> 
     <!-- My content with data-bind attributes --> 
    </span> 
    <!-- /ko --> 
+0

Quando verrà eseguito l'aggiornamento di jqmEnhance? Come sai che questo accadrà dopo che il contenuto interiore è stato creato piuttosto che prima? –

+0

Secondo la [documentazione] (http://knockoutjs.com/documentation/custom-bindings.html): * Ogni volta che le modifiche osservabili associate, KO chiamerà il callback dell'aggiornamento * – GiddyUpHorsey

+0

Ok, quindi il MyValue dovrebbe essere l'ultimo oggetto da modificare dopo che tutte le altre modifiche hanno attivato gli aggiornamenti. –