我有一个用于创建/更新活动的表单,它是一个像这样的有状态小部件:
class ActivityForm extends StatefulWidget {
final Activity activity;
final bool isEdit;
const ActivityForm({Key key, this.activity, this.isEdit}) : super(key: key);
@override
_ActivityFormState createState() => _ActivityFormState();
}
class _ActivityFormState extends State<ActivityForm> {
final _formKey = GlobalKey<FormState>();
List<int> activityDetailIdToBeDeleted;
...
void submitHandler() async {
setState(() {
_isLoading = true;
});
// Mapping input field to activity model
Activity activity = Activity(
id: widget.activity.id,
tanggal: _tanggalController.text,
uraianKegiatan: _uraianKegiatanController.text,
pic: _picController.text,
jumlahTim: int.parse(_jumlahTimController.text),
kendala: _kendalaController.text,
penyelesaian: _penyelesaianController.text,
approverUserId: selectedApprovalUser,
rincianPekerjaan: rincianPekerjaanList,
status: 'PENDING');
if (widget.isEdit) {
await Provider.of<ActivityProvider>(context, listen: false)
.updateActivity(activity, activityDetailIdToBeDeleted);
} else {
await Provider.of<ActivityProvider>(context, listen: false)
.createActivity(activity);
}
Navigator.pop(context);
}
在我的表单中有一些活动的详细列表。当我按删除时,它会添加 “待删除”列表中的活动详情:
IconButton(
icon: Icon(Icons.delete),
onPressed: () => removeRincianPekerjaan(
activityDetail.description),),
功能如下:
void removeRincianPekerjaan(desc) {
if (widget.isEdit) {
int detailId = rincianPekerjaanList
.where((element) => element.description == desc)
.first
.id;
if (!activityDetailIdToBeDeleted.contains(detailId))
activityDetailIdToBeDeleted.add(detailId);
print(activityDetailIdToBeDeleted);
}
setState(() {
rincianPekerjaanList
.removeWhere((element) => element.description == desc);
});
}
该 ID 列表将发送给提供者,如下所示:
Future<bool> updateActivity(
Activity activity, List<int> activityDetailToBeDeleted) async {
final response = await ActivityService()
.updateActivity(activity.id.toString(), activity.toMap());
if (response != null) {
// Update Success.
if (response.statusCode == 200) {
var body = json.decode(response.body);
removeActivityToList(activity);
activity = Activity.fromMap(body['activity']);
addActivityToList(activity);
if (activityDetailToBeDeleted.isNotEmpty) {
print("to be deleted is not empty.");
print("ID to be deleted: ${activityDetailToBeDeleted.join(",")}");
final res = await ActivityService()
.deleteActivityDetail(activityDetailToBeDeleted.join(","));
if (res.statusCode == 204) {
print('ID DELETED.');
return true;
}
}
return true;
}
// Error unauthorized / token expired
else if (response.statusCode == 401) {
var reauth = await AuthProvider().refreshToken();
if (reauth) {
return await createActivity(activity);
} else {
return Future.error('unauthorized');
}
}
return Future.error('server error');
}
return Future.error('connection failed');
}
问题是如果列表为空,或者我没有将 id 添加到列表中,构建器上下文不为空,但是如果我将一个 id 添加到“要删除”的列表中,Navigator.pop(context)
会抛出错误,因为 context
为空。我不明白为什么它会变成空。
答案 0 :(得分:1)
您的 [上下文] 必须来自 build() 方法。像这样。
void submitHandler(BuildContext context) async {
setState(() {
_isLoading = true;
});
// Mapping input field to activity model
Activity activity = Activity(
id: widget.activity.id,
tanggal: _tanggalController.text,
uraianKegiatan: _uraianKegiatanController.text,
pic: _picController.text,
jumlahTim: int.parse(_jumlahTimController.text),
kendala: _kendalaController.text,
penyelesaian: _penyelesaianController.text,
approverUserId: selectedApprovalUser,
rincianPekerjaan: rincianPekerjaanList,
status: 'PENDING');
if (widget.isEdit) {
await Provider.of<ActivityProvider>(context, listen: false)
.updateActivity(activity, activityDetailIdToBeDeleted);
} else {
await Provider.of<ActivityProvider>(context, listen: false)
.createActivity(activity);
}
SchedulerBinding.instance.addPostFrameCallback((_) {
Navigator.pop(context);
});
}