问题
The below example shows an observable array being populated from with Json, which then allows you to filter the results into 2 lists based on 'type'.
This all works fine until I try and load exactly the same Json from a ajax call!
The strange thing is if i put an alert in the script it then works fine...
http://jsfiddle.net/spdKE/3/
<h2>Brand</h2>
<ul id="list-dimensions" data-bind="foreach: filteredDimensions('BRAND')">
<li>
<div class="item">ID</div> <span data-bind="text: $data.id"</span>
</li>
</ul>
<h2>Area</h2>
<ul id="list-dimensions" data-bind="foreach: filteredDimensions('AREA')">
<li>
<div class="item">ID</div> <span data-bind="text: $data.id"</span>
</li>
</ul>
function ProductDimensionsViewModel () {
var self = this;
self.dimensions = ko.observableArray();
var baseUri = 'api/product_dimensions.php';
/*$.getJSON(baseUri, function(data){
success: self.dimensions = data;
});*/
$.ajax({
type: 'GET',
url: baseUri,
data: {},
context: this,
success: function(data) {
self.dimensions = data
},
dataType: 'json'
});
self.filteredDimensions = function(type) {
return $.map(self.dimensions, function(dimension) {
if (dimension.type == type) {
return dimension;
}
});
}
}
ko.applyBindings(new ProductDimensionsViewModel());
回答1:
You are replacing the variable, not updating it:
...
success: function(data) {
self.dimensions = data
},
...
Observables are updated this way:
...
success: function(data) {
self.dimensions(data)
},
...
I wouldn't use filteredDimensions('AREA')
because this gets call as soon as your page is rendered. Use observables, store in a variable currentFilter
the value and then through a template load the proper view. Also, if you only have two filters, a better approach is just to have two methods: filterByArea
and filterByBrand
.
EDIT: Added example: http://jsfiddle.net/jjperezaguinaga/spdKE/4/
来源:https://stackoverflow.com/questions/14163763/knockout-js-ajax-call-not-populating-observable-array