Here is a weird race condition happening with knockoutjs. I’m setting two observables independantly using ajax calls. One is a list, the other is a single value. The weird thing is when I load the single value before the list, it won’t bind correctly. Any suggestions?
JsFiddle: http://jsfiddle.net/JasonMore/bxfXd/110/
View
<form data-bind='submit:addItem'>
Add item: <input data-bind='value:itemToAdd, valueUpdate: "afterkeydown"' type='text' />
<button data-bind='enable: isAddButtonEnabled' type='submit'>Add</button>
</form>
<p>Your values:</p>
<select data-bind='options:allItems, value:selectedItems' height='5'> </select>
<div>
<button data-bind='click: removeSelected'>Remove</button>
<button data-bind='click: function() { allItems.sort() }, enable: allItems().length > 1'>Sort</button>
</div>
</div>
Code
var betterListModel = function() {
var self = this;
// properties
this.itemToAdd = new ko.observable("");
this.allItems = new ko.observableArray();
this.selectedItems = new ko.observable('');
// computed
this.isAddButtonEnabled = ko.computed(function() {
return self.itemToAdd().length > 0
});
//methods
this.addItem = function() {
if ((this.itemToAdd() != "") && (this.allItems.indexOf(this.itemToAdd()) < 0)) this.allItems.push(this.itemToAdd());
this.itemToAdd("");
}
this.removeSelected = function() {
this.allItems.removeAll(this.selectedItems());
this.selectedItems();
} };
var view = new betterListModel();
ko.applyBindings(view);
// load $.ajax({
url: '/echo/json/',
type: 'post',
data: {
json: $.toJSON("Ham"),
delay: 1
},
success: function(data) {
view.selectedItems(data);
} });
$.ajax({
url: '/echo/json/',
type: 'post',
data: {
json: $.toJSON(["Fries", "Eggs Benedict", "Ham", "Cheese"]),
delay: 2
},
success: function(data) {
$.each(data, function(index, value) {
view.allItems.push(value);
});
} });
Try this–>
// Whenever the states changes, reset the selectedState selection