我正在尝试使用"天文台"在Dart中编写一个简单的单页Web应用程序。包。它应该做的是显示" Name"中的所有数据。收集,检索用户的输入,最后将该输入添加到屏幕列表和集合。输入会被添加到无序列表中,但所有这些都会发生。我不确定我做错了什么。这是我的Dart代码:
import 'dart:html';
import 'package:objectory/objectory_browser.dart';
class Name extends PersistentObject {
String get collectionName => "Name";
String get first => getProperty("first");
set first(String value) => setProperty("first", value);
String get last => getProperty("last");
set last(String value) => setProperty("last", value);
}
const uri = 'mongodb://localhost/dosdart1';
registerClasses() {
objectory.registerClass(Name, () => new Name(), () => new List<Name>());
}
void main() {
objectory = new ObjectoryWebsocketBrowserImpl(uri, registerClasses, false);
loadNames();
querySelector('#output').text = 'Your Dart app is running.';
var btn = querySelector('#btn');
btn.onClick.listen(addName);
}
Future display(name) {
var completer = new Completer();
name.fetchLinks().then((__) {
var ul = querySelector('#names');
var li = new LIElement()
..appendText("${name.first} ${name.last}");
ul.append(li);
completer.complete(true);
});
return completer.future;
}
loadNames() {
objectory.initDomainModel().then((_) {
return objectory[Name].find();
}).then((names){
return Future.wait(names.map((name) => display(name)));
}).then((_) {
objectory.close();
});
}
addName(MouseEvent e) {
var name = new Name();
InputElement firstElement = querySelector('#first');
InputElement lastElement = querySelector('#last');
name.first = firstElement.value;
name.last = lastElement.value;
objectory.initDomainModel().then((_){
name.save();
return;
}).then((_) {
objectory.close();
});
display(name);
}
这是我的网页:
<!DOCTYPE html>
<!--
Copyright (c) 2015, <your name>. All rights reserved. Use of this source code
is governed by a BSD-style license that can be found in the LICENSE file.
-->
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="scaffolded-by" content="https://github.com/google/stagehand">
<title>hybrid_dart</title>
<link rel="stylesheet" href="styles.css">
<script async src="main.dart" type="application/dart"></script>
<script async src="packages/browser/dart.js"></script>
</head>
<body>
<div id="output"></div>
<p><label for="first">First name:</label><input type="text" id="first" name="first"></p>
<p><label for="last">Last name:</label><input type="text" name="last" id="last"></p>
<p><button id="btn" name="btn" title="Insert">Insert</button></p>
<ul id="names">
</ul>
</body>
</html>
有人有什么想法吗?
答案 0 :(得分:2)
您需要连结期货以确保它们按顺序执行。如果每次通话都返回Future
或同步值,我就不会看到它,因此我可能会在这里和那里错过(我添加/* await */
有疑问)。
新的async
/ await
功能可以更轻松地处理异步代码,因此我将所有then(...)
更改为async
/ await
。
main() async {
objectory = new ObjectoryWebsocketBrowserImpl(uri, registerClasses, false);
await loadNames();
querySelector('#output').text = 'Your Dart app is running.';
var btn = querySelector('#btn');
btn.onClick.listen(addName);
}
Future display(name) async {
await fetchLinks();
var ul = querySelector('#names');
var li = new LIElement()
..appendText("${name.first} ${name.last}");
ul.append(li);
}
Future loadNames() async {
await objectory.initDomainModel();
var names = await objectory[Name].find();
await Future.wait(names.map((name) => display(name)));
/* await */ objectory.close();
}
Future addName(MouseEvent e) async {
var name = new Name();
InputElement firstElement = querySelector('#first');
InputElement lastElement = querySelector('#last');
name.first = firstElement.value;
name.last = lastElement.value;
await objectory.initDomainModel();
name.save();
/* await */ objectory.close();
await display(name);
}
没有async
/ await
,它应该像
void main() {
objectory = new ObjectoryWebsocketBrowserImpl(uri, registerClasses, false);
loadNames().then((_) {
querySelector('#output').text = 'Your Dart app is running.';
var btn = querySelector('#btn');
btn.onClick.listen(addName);
});
}
Future display(name) {
return name.fetchLinks().then((__) {
var ul = querySelector('#names');
var li = new LIElement()
..appendText("${name.first} ${name.last}");
ul.append(li);
});
}
Future loadNames() {
return objectory.initDomainModel().then((_) {
return objectory[Name].find();
}).then((names){
return Future.wait(names.map((name) => display(name)));
}).then((_) {
/* return */ objectory.close();
});
}
Future addName(MouseEvent e) {
var name = new Name();
InputElement firstElement = querySelector('#first');
InputElement lastElement = querySelector('#last');
name.first = firstElement.value;
name.last = lastElement.value;
return objectory.initDomainModel().then((_){
name.save();
return;
// if "name.save();" returns a Future this should be
// return name.save();
}).then((_) {
/* return */ objectory.close();
}).then((_) {
return display(name);
});
}
答案 1 :(得分:0)
我终于使用forcemvc和服务器端MongoDB解决了这个谜题:
library serverweb2;
// add code to names() to retrieve all the names
// change names.html accordingly
import "package:forcemvc/force_mvc.dart";
import "package:objectory/objectory_console.dart";
import 'dart:async';
main(List<String> args) {
objectory = new ObjectoryDirectConnectionImpl('mongodb://127.0.0.1/serverweb2',
registerClasses, false);
var app = new WebApplication();
app.start();
// print('Hello world!');
}
@Controller
class Controllers {
@RequestMapping(value: "/", method: RequestMethod.GET)
String index(req, Model model) {
return "index";
}
@RequestMapping(value: "/names", method: RequestMethod.POST)
Future names(ForceRequest req, Model model) {
objectory.initDomainModel().then((_) {
req.getPostParams().then((params) {
var first = params['first'] as String;
var last = params['last'] as String;
var name = new Name()
..firstName = first
..lastName = last;
name.save();
return objectory[Name].find();
}).then((names) {
model.addAttribute('names', names);
return;
}).then((_){
req.async("names");
objectory.close();
});
});
return req.asyncFuture;
}
}
class Name extends PersistentObject {
String get collectionName => "Name";
String get firstName => getProperty("first_name");
set firstName(String value) {
setProperty("first_name", value);
}
String get lastName => getProperty('last_name');
set lastName(String value) {
setProperty('last_name', value);
}
@override
String toString() => "$firstName $lastName";
}
registerClasses() {
objectory.registerClass(Name, () => new Name(), () => new List<Name>());