我有一个ember组件,它有一个包含表的模板。在我的组件中,我想向第三方服务发出ajax调用,并获取一些数据。在获得这些数据后,我将不得不根据输入进行另一个后续的ajax调用。由于这需要时间,所以我希望在ajax调用完成时一个接一个地更新视图。从视觉意义上讲,这将是在处理一个请求后向表中添加一个新行。
目前,ember只允许我们通过路由器中的model()
方法传递数组对象。
我研究了几个像List视图这样的项目,但它并没有解决上述问题。
编辑:-
以下是我目前正在做的事情-
import Ember from 'ember';
export default Ember.Route.extend({
model() {
var list = [];
var promise = $.ajax({
type: 'GET',
url: 'thirdPartyService'
});
promise = promise.then(function(data){
data = JSON.parse(data);
return data[1];
});
promise.then(function(data){
for (var i = 0; i < data.length; i++) {
var idea = data[i];
var url = "thirdPartyService";
var secondPromise = $.ajax({
type: 'GET',
url: url,
dataType: "text"
});
secondPromise = secondPromise.then(function(data){
var result = x2js.xml_str2json(data);
return result;
});
secondPromise.then(function(data){
list.pushObject(item);
});
return secondPromise;
}
});
return list;
}
});
我的模板
<tbody>
{{#each model as |idea|}}
<tr>
<td><input type="checkbox" name="id" value="{{idea.id}}"></td>
<td>{{idea.field4}}</td>
<td>{{idea.field5}}</td>
<td>{{idea.field}}</td>
<td>{{idea.field2}}</td>
<td>{{idea.field3}}</td>
</tr>
{{/each}}
</tbody>
当列表更改时,Ember视图将被渲染。我想做的是在调用list.pushObject(item);
时向表中添加一行。目前-我看到视图正在等待,直到所有东西都返回。
此外,这个应用程序是一个电子应用程序——因此,我没有后端,也没有使用ember数据。我打电话给几个第三方服务,所以没有成员模型涉及。
更新:
演示:https://ember-twiddle.com/eb79994c163dd1db4e2580cae066a318
在这个演示中,我下载了你的github数据和repos列表,所以当两个api调用都返回时,模型钩子会返回。。。并且最后它将提供回购名称的列表。
使用loading.hbs
,加载消息会自动出现,直到模型挂钩承诺得到解决。
在您的代码中,覆盖promise变量可能不是最好的方法,因为您覆盖了一个尚未解决的变量。
如果您想要更好的用户体验,最好是在模型中只有一个ajax调用,并返回该承诺。。。所以你的模型包含了第一个promise结果。。。您可以使用这些数据在控制器中触发promise并下载列表,这样用户就可以在下载列表之前看到表的标题和加载消息。
演示扩展到第二页:https://ember-twiddle.com/eb79994c163dd1db4e2580cae066a318
如果您必须在页面中处理更多的模型,我会使用RSVP.hash
在路由处理程序中下载它们。
// for example: app/routes/books.js, where books are the main model
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return Ember.RSVP.hash({
books: this.store.findAll('book'),
authors: this.store.findAll('author'),
libraries: this.store.findAll('library')
});
},
setupController(controller, model) {
const books = model.books;
const authors = model.authors;
const libraries = model.libraries;
this._super(controller, books);
controller.set('authors', authors);
controller.set('libraries', libraries);
},
});
在上面的示例中,控制器中有model
(带有图书列表)、authors
和libraries
,因此可以将这些数组转发给组件。
您是否使用Ember Data访问您的服务器API或第三方服务?在这种情况下,您可以在组件中注入store
服务,并像在路由处理程序中那样使用它。
其他选项使用闭包操作,所以您的操作将在控制器中,并且您可以从组件中调用这些操作,所以所有组件将只负责查看数据和其他片段。
在下面的示例中,我们创建了一个自包含的组件,其中您有一个按钮来启动一个操作,该操作将使用经典的jquery ajax调用从服务器下载数据,该调用被封装在promise中,因此您可以将这些promise链接起来并连续启动。
创建组件
$ ember g component my-component
模板app/templates/components/my-components.hbs
,带有按钮、标志和列表。
<button {{action 'downloadSomething'}}>Download</button>
in progress: {{downloadInProgress}}
{{#each downloaded as |item|}}
{{item.name}}
{{/each}}
连接的js文件app/components/my-components.js
import Ember from 'ember';
const { $ } = Ember;
export default Ember.Component.extend({
downloaded: [],
actions: {
downloadSomething() {
this.set('downloadInProgress', true);
this._getData('http://localhost:8080').then(
(response) => {
this.set('downloadInProgress', false);
this.get('downloaded').pushObjects(response.contacts);
},
(error) => {
// some error handling...
}
);
}
},
// this function wraps the ajax call in a Promise
_getData(url) {
return new Ember.RSVP.Promise((resolve, reject) =>
$.ajax(url, {
success(response) {
resolve(response);
},
error(reason) {
reject(reason);
}
})
);
}
});
在ajax响应中,我们将返回的Object推送到downloaded
数组中,因此它总是被添加到列表中。