![](/img/trans.png)
[英]How do I replace the contents of knockout js observable array with an array returned from a promise
[英]How to bind array of objects from Promise Knockout JS
我有一個通過yelp api返回帶有復雜對象數組的promise的方法。 我需要通過data-bind =“ foreach:objects”將其與標記綁定,但是我不能。 我需要了解如何在標記中綁定數據,以及如何在可觀察的數組中使用Promise。 有人可以幫忙嗎?
//getDataForPlaces var getDataForPlaces = function(addresses){ return Promise.all(Array.prototype.map.call(addresses, function(address) { return getLocationDesc(address); })); }; //getLocationDesc var getLocationDesc = function(address){ return new Promise(function(resolve, reject) { var parameters = []; parameters.push(['sort', sort]); parameters.push(['limit', limit]); parameters.push(['radius_filter', radius_filter]); parameters.push(['actionlinks', actionlinks]); parameters.push(['location', address]); parameters.push(['callback', 'callback']); parameters.push(['oauth_consumer_key', auth.consumerKey]); parameters.push(['oauth_consumer_secret', auth.consumerSecret]); parameters.push(['oauth_token', auth.accessToken]); parameters.push(['oauth_signature_method', 'HMAC-SHA1']); var message = { 'action' : 'http://api.yelp.com/v2/search', 'method' : 'GET', 'parameters' : parameters }; OAuth.setTimestampAndNonce(message); OAuth.SignatureMethod.sign(message, accessor); var parameterMap = OAuth.getParameterMap(message.parameters); $.ajax({ url : message.action, cache : true, method : message.method, data : parameterMap, dataType : 'jsonp', jsonp : 'callback', success : resolve, error : reject }); }); }; //View model function MapViewModel(){ var self = this; self.categories = ["Choose option", "Bars", "Gyms"]; var addresses = ["address","address, address", "address","address", "address"]; var yelp = new YelpDataProvider(); self.places = ko.observableArray(); yelp.getDataForPlaces(addresses).then(function(place){ self.places(place); }) } ko.applyBindings(new MapViewModel());
<ul data-bind="foreach: places "> <li data-bind="text: business[0].name"></li> </ul>
這里有一些概念上的問題。
如果MapViewModel()
是構造函數,則將使用new
調用它。 但是,構造函數的getLocationDesc()
方面是異步的,其結果是,按照書面規定, new MapViewModel()
將返回有效地仍在構造中的對象,並且無法訪問表示完成異步過程的承諾。 。
構造函數和異步性不能混在一起。
一種解決方法是將異步內容放入公共.getLocationsAsync()
方法中。 可能是這樣的:
function MapViewModel() {
var self = this;
self.categories = ["Choose option", "Bars", "Gyms"];
self.places = ko.observableArray();
var addresses = ["address", "address, address", "address", "address", "address"];
var yelp = new YelpDataProvider();
var locationsPromise = null;// a var in which to cache the promise created by this.getLocationsAsync()
this.getLocationsAsync = function() {
if(!locationsPromise) {
locationsPromise = Promise.all(addresses.map(yelp.getLocationDesc)).then(function(placeDescriptions) {
placeDescriptions.forEach(function(p) {
places.push(p);
});
return places;
});
}
return locationsPromise;
};
}
可能不是100%正確,但希望足以說明這一想法。
現在調用如下:
var mapViewModel = new MapViewModel();
mapViewModel.getLocationsAsync().then(function(places) {
// places is an observableArray
});
注意:要真正有用,您可能希望將addresses
和categories
傳遞給MapViewModel()
,否則每個實例都是相同的。 還是應該將MapViewModel()
改寫為單例?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.