Navigator 上 then 方法的语法问题
Syntax issue with then method on Navigator
我有以下代码片段:
_openEditListingDialog(Listing listing,
Function(Listing) onSubmittedCallback) async {
Navigator
.of(context)
.push(
new MaterialPageRoute<Listing>(
builder: (BuildContext context) {
return new ListingDialog.edit(listing);
},
fullscreenDialog: true,
),
)
.then((Listing newEntry) {
if (newEntry != null) {
newEntry.id = listing.id;
onSubmittedCallback(newEntry);
}
});
}
VSCode 抱怨 .then 行出现以下错误:
[dart] The argument type '(Listing) -> Null' can't be assigned to the parameter type '(Object) -> FutureOr<Null>'.
这是什么意思,我该如何更正?我是 dart 和 flutter 的新手,像这样的错误消息对我来说很神秘。我的代码基于这个例子:https://github.com/MSzalek-Mobile/weight_tracker/blob/v0.4.1/lib/home_page.dart.
你传递一个函数
Function(Listing) onSubmittedCallback) async {
// no return here
});
这意味着 Dart 推断 return 类型 Null
我想改成
FutureOr<Null> Function(Listing) onSubmittedCallback) async =>
并在末尾(代码的最后一行)删除 }
应该可以修复它。
如果你想保留函数体{...}
使用
FutureOr<Null> Function(Listing) onSubmittedCallback) async {
await Navigator
.of(context)
...
TBH 我不确定为什么 VS Code 将其标记为您的错误 - 我没有发现任何实质性错误,我的 VS Code 或 IntelliJ 也没有。我粘贴了你的代码,在添加了一个清单 class 之后,我一点问题都没有(为了记录,如果你粘贴了足够多的代码,当你遇到问题时,有人可以 运行 解决问题他们更容易帮助你)。
在这种特殊情况下,错误的行号可能会很有帮助。
也许确保你的 VS Code 和 Flutter 是最新的(我正在使用已经更新到 dart 2.0 的 Master channel/branch 所以它可能是它的一部分......)。
您可以尝试几件事。首先,您的 push
方法似乎没有选择正确的类型 - 我很确定您看到的错误是在它期望的 .then(...
和 Object 处告诉它是一个清单。您可以将 .push
更改为 .push<Listing>
以强制其成为 return 列表。
接下来,我实际上并不熟悉你用 Function(Listing) 做什么。我不认为这是正确的飞镖,或者至少不再是。我认为推荐的做法是 typedef-ing 一个具有正确参数类型的方法,即 typedef void ListingCallback(Listing listing);
然后使用它作为参数,如果你要使用回调(见后面的回答一个可以说是更好的选择)。
您做错的另一件事是 mis-using async
,很多人一开始似乎都在做 dart/flutter。如果你在方法签名中使用 async
,你不应该为 futures 使用 .then
,而应该使用 await
。请参阅有效飞镖的 here and this 部分。我已经 re-written 你的代码可以正确地做到这一点:
//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);
}
}
请注意,这也会删除导致您出现问题的整个函数。
此外,您可以只使用 futures 并删除方法签名中的 async
,但是您将必须确保实际 return 一个 future。
最后,您可以(应该)可能 returning Future 而不是传递回调。
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;
}
我有以下代码片段:
_openEditListingDialog(Listing listing,
Function(Listing) onSubmittedCallback) async {
Navigator
.of(context)
.push(
new MaterialPageRoute<Listing>(
builder: (BuildContext context) {
return new ListingDialog.edit(listing);
},
fullscreenDialog: true,
),
)
.then((Listing newEntry) {
if (newEntry != null) {
newEntry.id = listing.id;
onSubmittedCallback(newEntry);
}
});
}
VSCode 抱怨 .then 行出现以下错误:
[dart] The argument type '(Listing) -> Null' can't be assigned to the parameter type '(Object) -> FutureOr<Null>'.
这是什么意思,我该如何更正?我是 dart 和 flutter 的新手,像这样的错误消息对我来说很神秘。我的代码基于这个例子:https://github.com/MSzalek-Mobile/weight_tracker/blob/v0.4.1/lib/home_page.dart.
你传递一个函数
Function(Listing) onSubmittedCallback) async {
// no return here
});
这意味着 Dart 推断 return 类型 Null
我想改成
FutureOr<Null> Function(Listing) onSubmittedCallback) async =>
并在末尾(代码的最后一行)删除 }
应该可以修复它。
如果你想保留函数体{...}
使用
FutureOr<Null> Function(Listing) onSubmittedCallback) async {
await Navigator
.of(context)
...
TBH 我不确定为什么 VS Code 将其标记为您的错误 - 我没有发现任何实质性错误,我的 VS Code 或 IntelliJ 也没有。我粘贴了你的代码,在添加了一个清单 class 之后,我一点问题都没有(为了记录,如果你粘贴了足够多的代码,当你遇到问题时,有人可以 运行 解决问题他们更容易帮助你)。
在这种特殊情况下,错误的行号可能会很有帮助。
也许确保你的 VS Code 和 Flutter 是最新的(我正在使用已经更新到 dart 2.0 的 Master channel/branch 所以它可能是它的一部分......)。
您可以尝试几件事。首先,您的 push
方法似乎没有选择正确的类型 - 我很确定您看到的错误是在它期望的 .then(...
和 Object 处告诉它是一个清单。您可以将 .push
更改为 .push<Listing>
以强制其成为 return 列表。
接下来,我实际上并不熟悉你用 Function(Listing) 做什么。我不认为这是正确的飞镖,或者至少不再是。我认为推荐的做法是 typedef-ing 一个具有正确参数类型的方法,即 typedef void ListingCallback(Listing listing);
然后使用它作为参数,如果你要使用回调(见后面的回答一个可以说是更好的选择)。
您做错的另一件事是 mis-using async
,很多人一开始似乎都在做 dart/flutter。如果你在方法签名中使用 async
,你不应该为 futures 使用 .then
,而应该使用 await
。请参阅有效飞镖的 here and this 部分。我已经 re-written 你的代码可以正确地做到这一点:
//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);
}
}
请注意,这也会删除导致您出现问题的整个函数。
此外,您可以只使用 futures 并删除方法签名中的 async
,但是您将必须确保实际 return 一个 future。
最后,您可以(应该)可能 returning Future 而不是传递回调。
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;
}