Dart 导航器上then方法的语法问题
我有以下代码片段:Dart 导航器上then方法的语法问题,dart,flutter,Dart,Flutter,我有以下代码片段: \u openEditListingDialog(列表, 函数(列表)onSubmittedCallback(异步){ 领航员 .of(上下文) .推( 新材料路线( 生成器:(BuildContext上下文){ 返回新列表对话框。编辑(列表); }, fullscreenDialog:true, ), ) .然后((列出新条目){ if(newEntry!=null){ newEntry.id=listing.id; onSubmittedCallback(新条目); }
\u openEditListingDialog(列表,
函数(列表)onSubmittedCallback(异步){
领航员
.of(上下文)
.推(
新材料路线(
生成器:(BuildContext上下文){
返回新列表对话框。编辑(列表);
},
fullscreenDialog:true,
),
)
.然后((列出新条目){
if(newEntry!=null){
newEntry.id=listing.id;
onSubmittedCallback(新条目);
}
});
}
VSCode在上投诉。然后行出现以下错误:
[dart] The argument type '(Listing) -> Null' can't be assigned to the parameter type '(Object) -> FutureOr<Null>'.
[dart]参数类型“(列表)->Null”不能分配给参数类型“(对象)->FutureOr”。
这是什么意思?我该如何纠正?我不熟悉飞镖和颤栗,像这样的错误信息对我来说很神秘。我的代码基于以下示例:。传递函数
Function(Listing) onSubmittedCallback) async {
// no return here
});
这意味着Dart推断返回类型Null
我想把它改成
FutureOr<Null> Function(Listing) onSubmittedCallback) async =>
TBH我不确定为什么VS代码会将其标记为错误-我看不出它有任何实质性的错误,我的VS代码或IntelliJ也没有。我粘贴了你的代码,在添加了一个列表类之后,我一点问题都没有(作为记录,如果你粘贴了足够多的代码,当你遇到问题时,有人可以实际运行一些东西,这会让他们更容易帮助你) 在这种特殊情况下,错误的行号可能非常有用 也许要确保你的VS代码和颤振是最新的(我正在使用主通道/分支,它已经更新到dart 2.0,所以这可能是它的一部分…) 有几件事你可以试试。首先,您的
push
方法似乎没有选择正确的类型-我很确定您看到的错误在处。然后(…
在它期望和对象的位置,您告诉它是一个列表。您可以将更改为。push
以强制它返回列表
接下来,我不太熟悉您对函数(清单)所做的操作。我认为这不是正确的dart,至少不再是。我认为推荐的方法是使用正确的参数类型键入一个方法,即typedef void ListingCallback(清单清单)
然后使用它作为参数,如果您要使用回调(请参阅后面的答案中的一个更好的替代方法)
另一件你做错了的事,许多人在dart/FLART中一开始似乎都是这样做的,那就是错误地使用了async
。如果你在方法签名中使用async
,你不应该使用。然后使用,而应该使用等待。请看,这是有效的dart的一部分。我已经重新编写了你的代码来实现这一点rly:
//outside class somewhere
typedef void ListingCallback(Listing listing);
...
_openEditListingDialog(
Listing listing, ListingCallback onSubmittedCallback) async {
Listing newEntry = await Navigator.of(context).push<Listing>(
new MaterialPageRoute<Listing>(
builder: (BuildContext context) {
return new ListingDialog.edit(listing);
},
fullscreenDialog: true,
),
);
if (newEntry != null) {
newEntry.id = listing.id;
onSubmittedCallback(newEntry);
}
}
更改了它,但仍然不好。我不确定是否同意您的解释。我的理解是,push(Route)应该返回Future,在这种情况下,它应该是Future,然后应该接受Future(dynamic onValue(T value)).我真的不理解你的评论。你收到错误消息了吗?你尝试过我的答案的哪些变体?我不认为函数(…)与他遇到的问题有任何关系。谢谢@rmtmckenzie。你的第一个示例非常有效,解决了我的问题。我不必强制推送返回列表,在移动一些换行符后,代码对我来说可读性更强(我来自C#background)。我还对您将来的示例感兴趣,该示例将避免回调。我假定_openEditListingDialog的结果将通过result=wait _openEditListingDialog(…)访问,对吗?是的,这是正确的。只需确保将调用它的函数安全地转换为异步函数-例如,如果将void initState
更改为Future(void)initState
,它可能不会显示语法错误,但在运行时会出现问题。(请查看是否遇到此问题)。请注意,即使返回未来,也可以使用\u openEditListingDialog(…)。然后((listing){..做任何事情)
。
//outside class somewhere
typedef void ListingCallback(Listing listing);
...
_openEditListingDialog(
Listing listing, ListingCallback onSubmittedCallback) async {
Listing newEntry = await Navigator.of(context).push<Listing>(
new MaterialPageRoute<Listing>(
builder: (BuildContext context) {
return new ListingDialog.edit(listing);
},
fullscreenDialog: true,
),
);
if (newEntry != null) {
newEntry.id = listing.id;
onSubmittedCallback(newEntry);
}
}
Future<Listing> _openEditListingDialog(Listing listing) async {
Listing newEntry = await Navigator.of(context).push<Listing>(
new MaterialPageRoute<Listing>(
builder: (BuildContext context) {
return new ListingDialog.edit(listing);
},
fullscreenDialog: true,
),
);
if (newEntry != null) {
newEntry.id = listing.id;
}
return newEntry;
}