2013-03-04 14 views
5

Ok, więc to zaczyna doprowadzać mnie do szaleństwa. Od kilku godzin szukam i szukam, a każde rozwiązanie nie działa dla mnie. Tak, tak, to pytanie może być niepotrzebne, ale nie mogę się doczekać, aż moje życie zacznie działać.jQuery Mobile i Knockout.js szablon, stylowanie nie jest stosowane

Mam wiele pól wyboru generowanych przez szablon jquery, który jest databound za pośrednictwem knockout.js. Jednak okazuje się, że nie ma w swoim spisie treści. Afaik, to jest coś o telefonii komórkowej jQuery robi stylizacji przed nokautem renderes szablonu, więc kończy się unstyled. Próbowałem wiele metod bezskutecznie, więc mam nadzieję, że ktoś tutaj może zobaczyć, co robię źle.

(używam jQuery mobile 1.2.0, jQuery 1.8.2 i 2.2.1 nokaut)

To skrypty:

<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> 

Uwaga "poczta elektroniczna" jest strona otaczający” "element div, nie pokazany tutaj. I to jest 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> 

Alternatywna metoda wywoływania restyling (robi praca albo):

$(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'); 
}); 

Odpowiedz

3

Każdy generowane dynamicznie jQuery Mobile zawartość musi być ręcznie wzmocniona.

Można to zrobić na kilka sposobów, ale najczęściej można to zrobić za pośrednictwem jQuery Mobile funkcji .trigger(.

przykład:

  • Zwiększenie zawartości jedynie strona

    $('#page-id').trigger('create'); 
    
  • Zwiększenie całą stronę (zawartość nagłówka + + stopkę):

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

Jeśli chcesz dowiedzieć się więcej na ten temat, zobacz mój inny ARTICLE, aby być bardziej przejrzystym, jest to mój osobisty blog. Lub znajdź go HERE.

+0

Dziękuję za odpowiedź, ten mały artykuł jest bardzo pomocny w przyszłości. Próbowałem Twojej sugestii i mam niewielką zmianę w moim kodzie w moim oryginalnym wpisie, a nie działa. Próbowałem umieścić kod, który sprawia, że ​​nokaut w dokumencie na stroniebeforeshow i restyling na stronieinit, brzmi rozsądnie, ale nie działa. Czy masz sugestię, kiedy w moim kodzie powinien zostać uruchomiony? –

+0

Powinny być umieszczone po wygenerowaniu wszystkich pól wyboru. Jeśli robisz to wewnątrz pętli, spust ("create") musi przejść po pętli. I nie rób tego dla każdej iteracji pętli, to spowolni generowanie strony. Zrób to tylko raz, po wygenerowaniu całej zawartości dynamicznej. – Gajotres

+0

Ale to właśnie próbowałem zrobić, bez powodzenia. Jestem kompletnie zagubiony. –

5

Użyj niestandardowego powiązania (Knockout), aby wyzwolić jQuery Mobile na , aby zwiększyć liczbę dynamicznie tworzonych treści generowanych przez Knockout.

Oto prosty wiążący zwyczaj:

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

Użyj zwyczaj wiązania w HTML jak ta, gdzie myValue jest częścią modelu widoku, który zmienia się, powodując dynamiczną zawartość do wstawienia do 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> 

w moim przypadku, myValue był częścią wyraz w if wiążące, które wyzwalają zawartość mają być dodane do DOM.

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

Kiedy zostanie uruchomiona aktualizacja jqmEnhance? Skąd wiadomo, że stanie się to po utworzeniu wewnętrznej treści, a nie wcześniej? –

+0

Zgodnie z [dokumentacją] (http://knockoutjs.com/documentation/custom-bindings.html): * Za każdym razem, gdy powiązane obserwowalne zmiany, KO wywoła twój oddzwonienie aktualizacji * – GiddyUpHorsey

+0

Ok, więc MyValue powinna być ostatnia obiekt do zmiany po tym, jak wszystkie pozostałe zmiany wywołały aktualizacje. –