【问题标题】:How to bind array of objects from Promise Knockout JS如何从 Promise Knockout JS 绑定对象数组
【发布时间】:2016-05-18 08:21:47
【问题描述】:

我有一个方法,它通过 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>

复杂对象:

【问题讨论】:

  • 看起来你的方法是对的。类似的代码按预期工作jsfiddle.net/xe9geqhy/2 你在这里有什么self.places(place); 看起来,你用对象(而不是数组)填充一个 observableArray,然后在标记中尝试迭代它。
  • 我使用了你的建议,它有效,但是如何在标记中获取对象?
  • how to get the object in the markup 是什么意思?你能提供self.places 数组吗?
  • 如何使用 Knockout.js foreach 绑定来迭代这个 JSON(参见上面带有 json 模型的图片)?
  • 据我了解,您可以使用类似jsfiddle.net/xe9geqhy/3

标签: javascript knockout.js promise yelp


【解决方案1】:

这里有点概念问题。

如果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() 应该改写为单例?

【讨论】:

    猜你喜欢
    • 2014-06-09
    • 1970-01-01
    • 2018-09-21
    • 2018-12-17
    • 2018-10-19
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 2022-08-19
    相关资源
    最近更新 更多