2017-10-12 2 views
1

J'ai un exemple knock-out, en utilisant "Avec" de liaison pour créer une liste déroulante en cascade.Knockout "avec" liaison, liste déroulante en cascade, recharger les valeurs sélectionnées ne fonctionne pas

La liste déroulante fonctionne correctement, si je sélectionne les valeurs, 4 menus déroulants en cascade avec chaque option de sélection correspondante.

Cependant, je voudrais enregistrer la configuration déroulante, donc à un chargement de page, je pourrais récupérer les valeurs enregistrées, tout comme le préréglage des valeurs.

Déconnecter les valeurs que les observables obtiennent en appelant 'save', après avoir sélectionné dans la liste déroulante. Mais ne fonctionne pas lors de l'appel de 'loadPresetData', pour simuler le mappage des données dans les valeurs sélectionnées observables.

J'ai fourchu le violon ci-dessous. http://jsfiddle.net/turrytheman/3urLenmd/

var sampleModel=[{"products":[{"name":"1948 Porsche 356-A Roadster","year":[{"name":2015,"months":[{"name":"jan"},{"name":"april"},{"name":"dec"}]}]},{"name":"1948 Porsche Type 356 Roadster","year":[{"name":2014,"months":[{"name":"jan"},{"name":"april"},{"name":"dec"}]},{"name":2015,"months":[{"name":"oct"},{"name":"marc"},{"name":"feb"}]}]},{"name":"1949 Jaguar XK 120","year":[{"name":2019,"months":[{"name":"oct"},{"name":"jun"},{"name":"jul"}]},{"name":2013,"months":[{"name":"oct"},{"name":"marc"},{"name":"feb"}]}]}],"name":"Classic Cars"},{"products":[{"name":"1936 Harley Davidson El Knucklehead","year":[{"name":2011,"months":[{"name":"jan"},{"name":"nov"},{"name":"sep"}]}]},{"name":"1957 Vespa GS150","year":[{"name":2014,"months":[{"name":"jan"},{"name":"april"},{"name":"dec"}]},{"name":2015,"months":[{"name":"another"},{"name":"yet"},{"name":"another"}]}]}],"name":"Motorcycles"}]; 


var Cascading = function() { 
    var self = this; 
    self.category = ko.observable(); 
    self.product = ko.observable(); 
    self.years = ko.observable(); 
    self.month = ko.observable(); 

    // Whenever the category changes, reset the product selection 
    self.category.subscribe(function(val) { 
     self.product(undefined); 
    }); 
    self.product.subscribe(function(val) { 
     self.years(undefined); 
    }); 
    self.years.subscribe(function(val) { 
     self.month(undefined); 
    }); 

    // Operations 
    self.loadPresetData = function() { //simulating a load, recieved from AJAX, setting saved values 
     self.category(JSON.parse('{"products":[{"name":"1936 Harley Davidson El Knucklehead","year":[{"name":2011,"months":[{"name":"jan"},{"name":"nov"},{"name":"sep"}]}]},{"name":"1957 Vespa GS150","year":[{"name":2014,"months":[{"name":"jan"},{"name":"april"},{"name":"dec"}]},{"name":2015,"months":[{"name":"another"},{"name":"yet"},{"name":"another"}]}]}],"name":"Motorcycles"}')); 
     self.product(JSON.parse('{"name":"1936 Harley Davidson El Knucklehead","year":[{"name":2011,"months":[{"name":"jan"},{"name":"nov"},{"name":"sep"}]}]}')); 
     self.years(JSON.parse('{"name":2015,"months":[{"name":"jan"},{"name":"april"},{"name":"dec"}]}')); 
     self.month(JSON.parse('{"name":"april"}')); 
} 
    self.save = function() { 
     var data = {"category": ko.toJSON(ko.toJS(self.category)), 
        "product": ko.toJSON(ko.toJS(self.product)), 
        "years": ko.toJSON(ko.toJS(self.years)) , 
        "month": ko.toJSON(ko.toJS(self.month)) 
        } 
     console.log(data); 
    }; 
}; 

ko.applyBindings(new Cascading()); 

HTML:

<div class='liveExample'> 
    <div> 
     <select data-bind='options: sampleModel, optionsText: "name", optionsCaption: "Select...", value: category'> </select> 
    </div> 
    <div data-bind="with: category"> 
     <select data-bind='options: products, optionsText: "name", optionsCaption: "Select...", value: $parent.product'> </select> 
    </div> 
     <div data-bind="with: product"> 
     <select data-bind='options: year, optionsText: "name", optionsCaption: "Select...", value: $parent.years'> </select> 
    </div> 
     <div data-bind="with: years"> 
     <select data-bind='options: months, optionsText: "name", optionsCaption: "Select...", value: $parent.month'> </select> 
    </div> 
    <button data-bind='click: loadPresetData'>Load</button> 
    <button data-bind='click: save'>Save</button> 

    <div style="color: red"data-bind="text:'Category :' + ko.toJSON(category)"></div> 
    <div style="color: green"data-bind="text:'Product :' + ko.toJSON(product)"></div> 
    <div style="color: blue"data-bind="text:'Year :' + ko.toJSON(years)"></div> 
    <div style="color: black"data-bind="text:'Months :' + ko.toJSON(month)"></div> 
</div> 

Répondre

1

Réponse courte: Les listes déroulantes ne reçoivent pas parce que le object mis en vous paramétrez à self.category() et d'autres listes déroulantes dans loadPresetData n'existez pas sampleModel (ou sampleProductCategories en le violon).

Oui, il y a un objet qui ressemble comme et a les mêmes propriétés et les tableaux imbriqués que l'objet JSON.parse() crée, mais ils sont totalement différents objets . Ils échoueraient Strict Equality Comparison or "=== comparison". Vous pouvez prouver cette hypothèse en définissant le category et d'autres valeurs en cascade à partir du tableau sampleProductCategories lui-même.

self.loadPresetData = function() { 
    self.category(sampleProductCategories[1]); 
    self.product(sampleProductCategories[1].products[0]); 
    self.years(sampleProductCategories[1].products[0].year[0]); 
    self.month(sampleProductCategories[1].products[0].year[0].months[0]); 
}; 

Maintenant, quand category est mis à jour, knock-out va et recherche cet objet dans sampleProductCategories. Il existe et par conséquent, category ne sera pas défini sur undefined.

Voici un updated fiddle

+0

Merci beaucoup, c'est exactement ce que je voulais. J'aurais dû penser à cette approche, mais je me suis retrouvé coincé dans la même direction ... Bonne réponse, courte et concise. – fntstk