我注意到在执行服务器调用时发生了以下情况,这里出了什么问题!
getItems(){
print('getItems');
request = new HttpRequest();
request.onReadyStateChange.listen(onData_getItems);
request.open('POST', host+'/getItems');
request.send(' ');
}
onData_getItems(_){
print('call'); // --> printed 4 times!!
if (request.readyState == HttpRequest.DONE && request.status == 200) {
print('Data loaded successfully..';
print(request.responseText); // --> printed 1 time!!
for(Map item in JSON.decode(request.responseText)){
LineItem..children.add(new OptionElement(value: item['Code'], data: item['Name']));
}
}
else if (request.readyState == HttpRequest.DONE &&
request.status == 0) {
print("could not connect to server, contact your admin");
}
else print('something else'); // --> printed 3 times
}
以上是在我的自定义元素中执行的:
class getPurchaseLines extends HtmlElement {
static final tag = 'get-POlines';
factory getPurchaseLines() => new Element.tag(tag);
var shadow, LineItem, LineQty, Lineprice, clsBtn;
getPurchaseLines.created() : super.created() {
shadow = this.createShadowRoot();
LineItem = new SelectElement()
..children.add(new OptionElement(value: '0', data:'Stock Code'));
LineQty = new InputElement()..type='number'..placeholder='Qty'..style.width='50px';
Lineprice = new InputElement()..type='number'..placeholder='price'..style.width='50px';
LineQty.onKeyUp.listen((e){if(LineQty.checkValidity() == false)LineQty.value='0';});
Lineprice.onKeyUp.listen((e){if(Lineprice.checkValidity() == false)Lineprice.value='0';});
shadow.host
..style.position='relative'
..style.display='inline-block'
..style.verticalAlign = 'top'
..style.backgroundColor = '#ffffff'
..style.boxShadow = '1px 1px 5px #333333'
..style.boxSizing = 'border-box'
..style.marginTop='2px'
..style.padding = '4px'
..style.paddingRight='30px'
..style.borderRadius='2px'
..style.fontSize='14px'
..style.transition = 'all 0.2s ease-in';
clsBtn
..onClick.listen((e)=> this.remove())
..style.position='absolute'
..style.right = '5px'
..style.top = '5px'
..style.color = 'black'
..style.cursor = 'pointer'
..style.zIndex = '1'
..style.fontSize = '16px'
..style.fontWeight = 'solid'
..classes.add('ion-close-circled')
..text='x'
;
shadow.nodes..add(LineItem)..add(LineQty)..add(Lineprice)..add(clsBtn);
}
在我的函数中调用如下:
Future fonixFuture() => new Future.value(true);
for (var line in orderLines){
fonixFuture()
.then((_)=> LineDisplay = new getPurchaseLines())
.then((_)=> LineDisplay.getItems())
.then((_)=> this.parent.nodes.add(LineDisplay))
.then((_)=>print(this.parent.nodes));
}
并且只有最后一个元素 (LineDisplay) 显示正确的 getItem() 结果。例如,如果我有 4 条线,则 LineDisplay 为:
- 在辅导员中打印“call”16 次
- 在浏览器中显示元素 LineDisplay 4 次
- 前 3 个“LineDisplay”中的 items 字段为空,而最后一个显示正确执行的项目。
附上问题说明。
更新
收到答案后,4 个响应问题已得到解决,但仍然仅在最后一个元素中收到输出!更新后的代码是:
return Future.forEach(orderLines, (ol) {
return fonixFuture()
.then((_)=>print(ol))
.then((_)=> LineDisplay = new getPurchaseLines())
.then((_)=> LineDisplay..getItems())
.then((_)=> this.parent.nodes.add(LineDisplay))
.then((_)=>print(this.parent.nodes));
});
自定义元素是:
part of fonix_client_library;
class getPurchaseLines extends HtmlElement {
static final tag = 'get-POlines';
factory getPurchaseLines() => new Element.tag(tag);
var shadow, LineItem, LineQty, Lineprice;
getPurchaseLines.created() : super.created() {
shadow = this.createShadowRoot();
LineItem = new SelectElement()
..children.add(new OptionElement(value: '0', data:'Stock Code'));
LineQty = new InputElement()..type='number'..placeholder='Qty'..style.width='50px';
Lineprice = new InputElement()..type='number'..placeholder='price'..style.width='50px';
LineQty.onKeyUp.listen((e){if(LineQty.checkValidity() == false)LineQty.value='0';});
Lineprice.onKeyUp.listen((e){if(Lineprice.checkValidity() == false)Lineprice.value='0';});
shadow.host
..style.position='relative'
..style.display='inline-block'
..style.verticalAlign = 'top'
..style.backgroundColor = '#ffffff'
..style.boxShadow = '1px 1px 5px #333333'
..style.boxSizing = 'border-box'
..style.marginTop='2px'
..style.padding = '4px'
..style.paddingRight='30px'
..style.borderRadius='2px'
..style.fontSize='14px'
..style.transition = 'all 0.2s ease-in';
shadow.nodes..add(LineItem)..add(LineQty)..add(Lineprice);
}
getItems(){
print('getItems');
request = new HttpRequest();
request.onReadyStateChange.listen(onData_getItems);
request.open('POST', host+'/getItems');
request.send(' ');
}
onData_getItems(_){
if (request.readyState != HttpRequest.DONE) return;
else
print('responce recieved..: ${request.responseText}');
if (request.readyState == HttpRequest.DONE && request.status == 200) {
fonixFooter.innerHtml='Items retreived..';
print('responce after checking ifItemsretrieved..: ${request.responseText}');
for(Map item in JSON.decode(request.responseText)){
LineItem..children.add(new OptionElement(value: item['Code'], data: item['Name']));
}
}
else if (request.readyState == HttpRequest.DONE &&
request.status == 0) {
print('no server..');
}
}
}
第二个屏幕截图显示更新后的输出
最佳答案
您收听一个流,预计会收到多个事件。
http://www.w3schools.com/jsref/prop_doc_readystate.asp说
此属性返回四个值之一:
- 未初始化 - 尚未开始加载
- 正在加载 - 正在加载
- 交互式 - 已加载足够的内容并且用户可以与其交互
- 完成 - 满载
如果您对未初始化
、加载
、交互式
不感兴趣,您可以检查
onData_getItems(_){
if (request.readyState != HttpRequest.DONE) return;
print('call'); // --> printed 1 time
更新(第二期)
在 forEach
中执行异步函数并不像您期望的那样工作
而不是
for (var line in orderLines){
使用
return Future.forEach(orderlines, (ol) {
return fonixFuture()
.then((_)=> LineDisplay = new getPurchaseLines())
.then((_)=> LineDisplay.getItems())
.then((_)=> this.parent.nodes.add(LineDisplay))
.then((_)=>print(this.parent.nodes));
});
你在没有明显原因的情况下人为地引入异步执行,这看起来有点奇怪
Future fonixFuture() => new Future.value(true);
因此我很难说出如何将上述代码片段集成到您的应用代码中。
如果问题仍然存在,我建议您创建一个新问题。
更新
return Future.forEach(orderLines, (ol) {
print(ol);
LineDisplay = new getPurchaseLines();
return LineDisplay.getItems()
.then((success) {
if(success) {
parent.nodes.add(LineDisplay);
print(this.parent.nodes);
} else {
print('getItems() failed!');
} // <== added
});
});
Future getItems(){
print('getItems');
request = new HttpRequest();
Completer completer = new Completer();
request.onReadyStateChange.listen((_) => onData_getItems(completer)); // <== changed
request.open('POST', host+'/getItems');
request.send(' ');
return completer.future;
}
onData_getItems(Completer completer) {
if (request.readyState != HttpRequest.DONE) {
return;
} else {
print('responce recieved..: ${request.responseText}');
}
if (request.status == 200) {
fonixFooter.innerHtml='Items retreived..';
print('responce after checking ifItemsretrieved..: ${request.responseText}');
for(Map item in JSON.decode(request.responseText)){
LineItem..children.add(new OptionElement(value: item['Code'], data: item['Name']));
}
completer.complete(true);
} else if (request.readyState == HttpRequest.DONE && request.status == 0) {
print('no server..');
completer.complete(false);
// or completer.completeError('failed');
}
}
关于dart - 服务器回调发生 4 次而不是 1 次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26439092/