[英]couldnt render a json array from servlet in ember js
我正在尝试渲染从 ember 中的 java servlet 发送的 json 数组。 工作流程如下
1.向servlet发送一个ajax请求,servlet将返回jsonobject
2.我会得到 json object 并尝试在车把文件中渲染
问题是当我安慰它带有索引的响应时
0: {CAPACITY: '4', PRICE: '918', RTYPE: 'basic', ID: '4'}
1: {CAPACITY: '2', PRICE: '885', RTYPE: 'villa', ID: '8'}
2: {CAPACITY: '2', PRICE: '1579', RTYPE: 'villa', ID: '5'}
3: {CAPACITY: '1', PRICE: '1526', RTYPE: 'villa', ID: '1'}
但是服务器发送的是
{"CAPACITY":"4","PRICE":"918","RTYPE":"basic","ID":"4"}
{"CAPACITY":"2","PRICE":"885","RTYPE":"villa","ID":"8"}
{"CAPACITY":"2","PRICE":"1579","RTYPE":"villa","ID":"5"}
{"CAPACITY":"1","PRICE":"1526","RTYPE":"villa","ID":"1"}
controller 代码
export default class RoomselectController extends Controller {
@service router;
@tracked obj = null ;
@tracked price =0;
get res(){
var dis = this;
const mobile = "123123123";
$.ajax({
url:'My',
method : 'GET',
dataType:'json',
data : {mobile:mobile},
success:function(response){
console.log(response);
dis.price = response[0].PRICE;//when rendered this works
dis.obj = response;//when changed to dis.obj = response[0] it renders the first
return response[0];
},
error: function(xhr,status,error){
var errorMessage = xhr.status + ": " + xhr.statusText;
alert("error " + errorMessage);
}
})
}
.hbs 代码
<table border ="1">
<tr><td><b>Capacity</b></td><td><b>Price</b></td><td><b>Room Type</b></td><td><b>Room No</b></td></tr>
{{#each-in this.obj as |key value|}}
<td>{{value}}</td>
{{/each-in}}
</table>
它不工作,但是当我使用dis.obj = response[0]
它工作并只呈现第一个索引如何使它呈现每个数据?
JS + 反应性中的异步有点不重要——但是。 有许多抽象可以提供帮助。
这里有一个视频/谈话,讨论了这个问题,以及解决它的各种方法:“什么是最困难的时间?关于异步? ”——Jim Schofield,Emberconf 2022
要点如下:
this
吸气剂中设置任何东西)关于我在您的代码中看到的一些注释:
res
永远不会被访问,因此它无法运行。res
不返回任何东西,所以访问它没有意义——现代 ESLint 配置中有一个 lint 会抱怨 getter 不返回任何东西this.res
的东西,您将创建新的 ajax每次访问的请求。但! 将其转换为
each-in
输入执行此操作。我最喜欢的方法是使用Resource 。
使用库ember-resources
提供的实用程序有几种方法可以实现您想要的功能。
trackedFunction
这是一个包装 Resource 原语并提供一些 异步 state的实用程序。
您使用此实用程序的代码如下所示:
import { trackedFunction } from 'ember-resources/util/function';
export default class RoomselectController extends Controller {
@service router;
request = trackedFunction(this, async () => {
const mobile = '123123123';
// I'm constructing a custom promise here
// because I don't know if your $.ajax supports async/await
return new Promise((resolve, reject) => {
$.ajax({
url: 'My',
method: 'GET',
dataType: 'json',
data: { mobile },
success: (response) => resolve(response),
error: (xhr, status, error) => reject(`${status}: ${xhr.statusText}`),
});
});
});
get result() {
return this.request.value || [];
}
}
{{#if this.request.isPending}}
loading data...
{{/if}}
<table border ="1">
<thead>
<tr>
<th>Capacity</th>
<th>Price</th>
<th>Room Type</th>
<th>Room No</th>
</tr>
</thead>
<tbody>
{{#each this.result as |row|}}
<tr>
{{#each-in row as |key value|}}
{{value}}
{{/each-in}}
</tr>
{{/each}}
</tbody>
</table>
Resource
第二种方法是使用您自己的 state,由您创建并在自定义resource
中使用。
使用相同的模板,您可以实现这样的自定义资源:
import { use, resource } from 'ember-resources';
import { tracked } from '@glimmer/tracking';
class RequestState {
@tracked value;
@tracked error;
get isPending() {
return !this.error && !this.value;
}
}
export default class RoomselectController extends Controller {
@service router;
@use request = resource(({ on }) => {
const mobile = '123123123';
const state = new RequestState();
$.ajax({
url: 'My',
method: 'GET',
dataType: 'json',
data: { mobile },
success: (response) => state.value = response;,
error: (xhr, status, error) => state.error = `${status}: ${xhr.statusText}`,
});
return state;
});
get result() {
return this.request.value || [];
}
}
参考
Resource
的信息ember-resources
(库)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.