javascript - Using Knockout and Breeze with Cascading Dropdowns -
so i've been @ , forth quite long time now, i'll point.
i creating application based on hottowel template, i'm using knockout, breeze, q etc. i'm using breeze query data server, , load data first select (as options). changes selectedmodel observable , subscription triggers ( subscription current "solution", have used data-bind etc same results). subscription takes new selectedmodel value , uses data second observable. query passes , results stored in modelproperties observable array, yet ui not update second select (it's empty). strange thing is, pressing ctrl + f5 (i tried 50 times in row) populates correctly, never on first load.
tldr; 2 selects, selected option of first 1 defines query options of second one. queries work, observables populated, first select populated, second never on first boot on following ctrl+f5.
here snippets regarding piece of application: viewmodel:
define(['services/logger', 'services/datacontext'], function (logger, datacontext) { var models = ko.observablearray(); var modelproperties = ko.observablearray(); var selectedmodel = ko.observable(); var init = true; function activate() { logger.log('search view activated', null, 'search', true); return datacontext.getmodels(models); } var sub = selectedmodel.subscribe(function (newvalue) { return datacontext.getmodelproperties(modelproperties, newvalue); }); var vm = { activate: activate, models: models, selectedmodel: selectedmodel, modelproperties: modelproperties, title: 'search view' }; return vm;
the view's code:
<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> </head> <body id="one"> <select id="entityselect" class ="entityselect" name="first" data-bind="options: models, value: selectedmodel"> </select> <select id="propertyselect" class ="propertyselect" data-bind= 'options:modelproperties'></select> </body> </html>
and methods in datacontext:
var getmodels = function (modelsobservable) { var query = entityquery.from('models'); return manager.executequery(query) .then(querysucceeded) .fail(queryfailed); function querysucceeded(data) { logger.log("query succeeded", true); logger.log(data); if (modelsobservable) { modelsobservable(data.results); } logger.log('retrieved [models] remote data source', data, true); } function queryfailed(data) { logger.log(data.tostring(), data, true); } }; var getmodelproperties = function (propertiesobservable,modelname) { var query = entityquery.from('modelproperties').withparameters({ name: modelname }); return manager.executequery(query) .then(querysucceeded) .fail(queryfailed); function querysucceeded(data) { logger.log("query succeeded", null, true); logger.log(data); if (propertiesobservable) { propertiesobservable(data.results); } logger.log('retrieved [properties] remote data source', data, true); } function queryfailed(data) { logger.log(data.tostring(), data, true); } };
once again i'd point out queries pass, , observablearrays populated results (checked .peek() ).
here screenshots clarify problem: on first boot vs : http://i.imgur.com/8gd53yh.png
then, ctrl+f5 http://i.imgur.com/vzo8d70.png
i have tried pretty can think of, , googled came mind, no avail. appreciated! also, first post here apologize mistakes!
here few comments -
your view makes no sense. if using hottowel template there lot of mark-up not needed there, considering using durandal.js composition , additional mark-up hurting you.
if indeed loading 'subview' more or less should -
<select id="entityselect" class ="entityselect" name="first" data-bind="options: models, value: selectedmodel"></select> <select id="propertyselect" class ="propertyselect" data-bind='options:modelproperties'></select>
next, if using cascading dropdowns have mentioned method before , suggest everyone. make second dependent on first ko.computed.
var models = ko.observablearray(); var modelproperties = ko.computed(function () { var modelarr = ko.observablearray(); if (!selectedmodel()) { return modelarr; } datacontext.getmodelproperties(modelarr, selectedmodel().then(function() { return modelarr(); }); });
now modelproperties null until select model, go out , properties of model.
it's important understand difference between function declarations using. var myfunc = function () {}; constructor function , evaluate on view model instantiation. function myfunc () {} standard function , wait until called before evaluating.
Comments
Post a Comment