- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个 Flutter 应用程序,它由一个带有 Parse Server 背景的员工调度程序组成。该应用程序的工作原理如下:
1)用户打开应用程序;
2)该应用程序显示可用员工的卡片列表(如果服务器数据库中有一些)
3) 用户可以编辑、确认或删除员工可用性。
该应用程序正在运行。这意味着我也可以像从我的应用程序屏幕一样从我的解析服务器获取 CRUD 数据。
目标 :数据库中的每个数据更改都需要刷新(实时)用户屏幕,移除、删除或更新(更改的)数据本身。
我的想法 :使用 parse_server_sdk: ^2.0.1 作为依赖项(pubspec.yaml)并实现实时查询(如 github 文档 here)
问题 :编译后,尽管我的 AndroidStudio 在视觉上没有崩溃,我的应用程序本身也没有崩溃,但它向我显示(日志)“LiveQuery 不起作用,如果提供了 ParseConnectivityProvider”。
没有问题(main.dart):
void main() async{
runApp(MyApp());
}
导致问题:
void main() async{
//the following parameters are in other file (constants.dart)...they are working
Parse().initialize(
kParseApplicationId,
kParseServerUrl,
masterKey: kParseMasterKey,
clientKey: kParseClientKey,
debug: true,
liveQueryUrl: kLiveQueryUrl,
autoSendSessionId: true,
);
var dietPlan = ParseObject('DietPlan')
..set('Name', 'Ketogenic')
..set('Fat', 65);
await dietPlan.save();
var response = await dietPlan.save();
if (response.success) {
dietPlan = response.result;
}
//until here, the program works well.The data is inserted and retrieved, ok...but exactly here..the problem!
final LiveQuery liveQuery = LiveQuery(); //from here..this is causing problems
QueryBuilder<ParseObject> query =
QueryBuilder<ParseObject>(ParseObject('DietPlan'))
..whereEqualTo('intNumber', 1);
Subscription subscription = await liveQuery.client.subscribe(query);
subscription.on(LiveQueryEvent.delete, (value) {
print('*** DELETE ***: ${DateTime.now().toString()}\n $value ');
print((value as ParseObject).objectId);
print((value as ParseObject).updatedAt);
print((value as ParseObject).createdAt);
print((value as ParseObject).get('objectId'));
print((value as ParseObject).get('updatedAt'));
print((value as ParseObject).get('createdAt'));
});
runApp(MyApp());
}
我没有找到任何解决方案 googleing.Any 。经过多次研究,我得到(深入库)Parse.Initialize(...) 将connectivityProvider 作为其参数之一,但我没有填写该参数。
final LiveQuery liveQuery = LiveQuery();
有人可以帮我解决这个问题吗?提前致谢
// Copyright 2018 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:intl/intl.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:marca_horario/model/data.dart';
import 'package:marca_horario/network_utils/data_utils.dart';
import 'package:http/http.dart';
import 'package:parse_server_sdk/parse_server_sdk.dart';
import 'package:marca_horario/constants.dart';
void myLQ() async {
Parse().initialize(
kParseApplicationId,
kParseServerUrl,
masterKey: kParseMasterKey,
clientKey: kParseClientKey,
debug: true,
liveQueryUrl: kLiveQueryUrl,
autoSendSessionId: true,
);
var dietPlan = ParseObject('DietPlan')
..set('Name', 'Ketogenic')
..set('Fat', 65);
await dietPlan.save();
var response = await dietPlan.save();
if (response.success) {
dietPlan = response.result;
}
final LiveQuery liveQuery = LiveQuery();
QueryBuilder<ParseObject> query =
QueryBuilder<ParseObject>(ParseObject('DietPlan'))
..whereEqualTo('intNumber', 1);
Subscription subscription = await liveQuery.client.subscribe(query);
subscription.on(LiveQueryEvent.delete, (value) {
print('*** DELETE ***: ${DateTime.now().toString()}\n $value ');
print((value as ParseObject).objectId);
print((value as ParseObject).updatedAt);
print((value as ParseObject).createdAt);
print((value as ParseObject).get('objectId'));
print((value as ParseObject).get('updatedAt'));
print((value as ParseObject).get('createdAt'));
});
}
void main() async{
Parse().initialize(
kParseApplicationId,
kParseServerUrl,
masterKey: kParseMasterKey,
clientKey: kParseClientKey,
debug: true,
liveQueryUrl: kLiveQueryUrl,
autoSendSessionId: true,
);
var dietPlan = ParseObject('DietPlan')
..set('Name', 'Ketogenic')
..set('Fat', 65);
await dietPlan.save();
var response = await dietPlan.save();
if (response.success) {
dietPlan = response.result;
}
final LiveQuery liveQuery = LiveQuery();
QueryBuilder<ParseObject> query =
QueryBuilder<ParseObject>(ParseObject('DietPlan'))
..whereEqualTo('intNumber', 1);
Subscription subscription = await liveQuery.client.subscribe(query);
subscription.on(LiveQueryEvent.delete, (value) {
print('*** DELETE ***: ${DateTime.now().toString()}\n $value ');
print((value as ParseObject).objectId);
print((value as ParseObject).updatedAt);
print((value as ParseObject).createdAt);
print((value as ParseObject).get('objectId'));
print((value as ParseObject).get('updatedAt'));
print((value as ParseObject).get('createdAt'));
});
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate
],
supportedLocales: [const Locale('pt', 'BR')],
home: Home()
);
}
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
var _listTiles = List<String>();
Color _iconColor = Colors.black;
Color standardIconColor = Colors.black;
Color alternateIconColor = Colors.green;
TextEditingController _nameController = TextEditingController();
var _scaffoldKey = new GlobalKey<ScaffoldState>();
String standardTileTitle = "Adicione um horário disponível...";
String _titleTile = "Adicione um horário disponível...";
String _tileSubtitle = "Edite o nome do funcionário...";
int _selectedIndexBottomNavBar = 0;
final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = new GlobalKey<RefreshIndicatorState>();
@override
Widget build(BuildContext context) {
return RefreshIndicator(
key: _refreshIndicatorKey,
onRefresh: () async {
setState(() {
});},
child: Scaffold(
key: _scaffoldKey,
floatingActionButton: FloatingActionButton(
onPressed: () {
invokeDatePicker();
},
child: Icon(Icons.add),
),
bottomNavigationBar: bottomNavigationBar(),
appBar: AppBar(
title: Text('Marca Horário'),
),
// body: Center(
// child: Text('Hello World'),
body: bodyStartScreen()
),
);
}
Widget bottomNavigationBar(){
void _onItemTapped(int index) {
setState(() {
_selectedIndexBottomNavBar = index;
});
print(_selectedIndexBottomNavBar);
if(_selectedIndexBottomNavBar == 2){
DatePicker.showDateTimePicker(context,
showTitleActions: true,
minTime: DateTime(2020, 1, 1),
maxTime: DateTime(2021, 12, 31),
onChanged: (date) {
print('change $date');
},
onConfirm: (date) {
print('confirm $date');
_listTiles.add(DateFormat.yMMMEd('pt_BR').add_Hm().format(date).toString());
_titleTile = DateFormat.yMMMEd('pt_BR').add_Hm().format(date).toString();
setState(() {
});
},
currentTime: DateTime.now(),
locale: LocaleType.pt);
}
}
return BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Funcionário',
),
BottomNavigationBarItem(
icon: Icon(Icons.access_time),
label: 'Marcar',
),
],
currentIndex: _selectedIndexBottomNavBar,
selectedItemColor: Colors.amber[800],
onTap: _onItemTapped,
);
}
Widget bodyStartScreen(){
return Column(
children: [
//the main title of the screen
Padding(
padding: EdgeInsets.all(16.0),
child: Text("Horários Possíveis",
style: TextStyle(
fontSize: 18.0
),
),
),
//gets available employees and datetimes from the server
FutureBuilder(builder: (context,snapshot){
if (snapshot.data != null) {
List<Data> dataList = snapshot.data;
return Expanded(
child: ListView.builder(
itemBuilder: (_, position) {
return Card(
child: ListTile(
title: Text(dataList[position].dateTime),
subtitle: Text(dataList[position].employee),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(icon: Icon(Icons.edit), onPressed: () {
//Show dialog box to update item
showUpdateDialog(dataList[position]);
}),
IconButton(icon: Icon(Icons.check_circle, color: Colors.green,), onPressed: () {
}),
//Show dialog box to delete item
IconButton(icon: Icon(Icons.delete), onPressed: () {
deleteData(dataList[position].objectId);
}),
],
),
),
);
},
itemCount: dataList.length,
),
);
} else {
return Center(
child: CircularProgressIndicator(),
);
}
},
future: getDataList(),
),
Divider(
color: Colors.black,
),
scheduleTile()
],
);
}
void invokeDatePicker(){
DatePicker.showDateTimePicker(context,
showTitleActions: true,
minTime: DateTime(2020, 1, 1),
maxTime: DateTime(2021, 12, 31),
onChanged: (date) {
print('change $date');
},
onConfirm: (date) {
print('confirm $date');
_listTiles.add(DateFormat.yMMMEd('pt_BR').add_Hm().format(date).toString());
_titleTile = DateFormat.yMMMEd('pt_BR').add_Hm().format(date).toString();
setState(() {
});
},
currentTime: DateTime.now(),
locale: LocaleType.pt);
}
void showUpdateDialog(Data data) {
_nameController.text = data.employee;
showDialog(context: context,
builder: (_) => AlertDialog(
content: Container(
width: double.maxFinite,
child: TextField(
controller: _nameController,
decoration: InputDecoration(
labelText: "Atualizar funcionário disponível",
),
),
),
actions: <Widget>[
FlatButton(onPressed: () {
Navigator.pop(context);
data.employee = _nameController.text;
updateData(data);
}, child: Text("Atualizar")),
FlatButton(onPressed: () {
Navigator.pop(context);
}, child: Text("Cancelar")),
],
)
);
}
Widget scheduleTile(){
return Padding(
padding: EdgeInsets.only(bottom: 80.0),
child: Card(
color: Colors.grey,
child: ListTile(
title: Text(_titleTile),
subtitle: Text(_tileSubtitle),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
IconButton(
icon: Icon(
Icons.edit,
color: standardIconColor,
size: 20.0,
),
onPressed: () {
setState(() {
employeeAvailable();
});
},
),
IconButton(
icon: Icon(
Icons.check_circle_outline,
color: _iconColor,
size: 20.0,
),
onPressed: () {
setState(() {
(_titleTile != standardTileTitle) ? confirmSchedule() : fillTimeDialog();
});
},
)
],
),
),
),
);
}
void fillTimeDialog(){
showDialog(context: context,
builder: (_) => AlertDialog(
content: Container(
width: double.maxFinite,
child: Text("Insira o horário disponível!"),
),
actions: <Widget>[
FlatButton(onPressed: () {
Navigator.pop(context);
}, child: Text("OK")),
],
)
);
}
void employeeAvailable(){
showDialog(context: context,
builder: (_) => AlertDialog(
content: Container(
width: double.maxFinite,
child: TextField(
controller: _nameController,
decoration: InputDecoration(
labelText: "Funcionário",
),
),
),
actions: <Widget>[
FlatButton(onPressed: () {
Navigator.pop(context);
//addTodo();
setState(() {
_tileSubtitle = "Disponível: " + _nameController.text;
});
}, child: Text("Inserir")),
FlatButton(onPressed: () {
Navigator.pop(context);
setState(() {
_tileSubtitle = " ";
});
}, child: Text("Desfazer")),
],
)
);
}
void confirmSchedule(){
showDialog(context: context,
builder: (_) => AlertDialog(
content: Container(
width: double.maxFinite,
child: Text("Confirma disponibilidade?")
),
actions: <Widget>[
FlatButton(onPressed: () {
Navigator.pop(context);
//addTodo();
addData();
setState(() {
_iconColor = alternateIconColor;
_tileSubtitle = "Disponível: " + _nameController.text;
});
}, child: Text("Confirma")),
FlatButton(onPressed: () {
Navigator.pop(context);
setState(() {
_iconColor = standardIconColor;
_tileSubtitle = " ";
});
}, child: Text("Não")),
],
)
);
}
void addData() {
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Row(
children: <Widget>[
Text("Adicionando informações..."),
CircularProgressIndicator(),
],
mainAxisAlignment: MainAxisAlignment.spaceBetween,
),
duration: Duration(minutes: 1),
));
Data data = Data(employee: _tileSubtitle, dateTime: _titleTile);
DataUtils.addData(data)
.then((res) {
_scaffoldKey.currentState.hideCurrentSnackBar();
Response response = res;
if (response.statusCode == 201) {
//Successful
_nameController.text = "";
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Informações disponibilizadas!"), duration: Duration(seconds: 1),));
setState(() {
//Update UI
});
}
});
}
void deleteData(String objectId) {
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text("Excluindo disponibilidade..."),
CircularProgressIndicator(),
],
),
duration: Duration(minutes: 1),
),);
DataUtils.deleteData(objectId)
.then((res) {
_scaffoldKey.currentState.hideCurrentSnackBar();
Response response = res;
if (response.statusCode == 200) {
//Successfully Deleted
_scaffoldKey.currentState.showSnackBar(SnackBar(content: (Text("Disponibilidade excluída!")),duration: Duration(seconds: 1),));
setState(() {
});
} else {
//Handle error
}
});
}
void updateData(Data data) {
_scaffoldKey.currentState.showSnackBar(SnackBar(content: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text("Atualizando disponibilidade..."),
CircularProgressIndicator(),
],
),
duration: Duration(minutes: 1),
),);
DataUtils.updateData(data)
.then((res) {
_scaffoldKey.currentState.hideCurrentSnackBar();
Response response = res;
if (response.statusCode == 200) {
//Successfully Deleted
_nameController.text = "";
_scaffoldKey.currentState.showSnackBar(SnackBar(content: (Text("Disponibilidade atualizada!"))));
setState(() {
});
} else {
//Handle error
}
});
}
Future <List<Data>> getDataList() async{
List<Data> dataList = [];
Response response = await DataUtils.getDataList();
print("Code is ${response.statusCode}");
print("Response is ${response.body}");
if (response.statusCode == 200) {
var body = json.decode(response.body);
var results = body["results"];
for (var data in results) {
dataList.add(Data.fromJson(data));
}
} else {
//Handle error
}
return dataList;
}
}
data_utils.dart:
import 'dart:convert';
import 'package:http/http.dart';
import 'package:marca_horario/model/data.dart';
import 'package:marca_horario/constants.dart';
class DataUtils {
//static final String _baseUrl = "https://parseapi.back4app.com/classes/";
static final String _baseUrl = baseUrl;
//CREATE
static Future<Response> addData(Data data) async {
String apiUrl = _baseUrl + "Data";
Response response = await post(apiUrl,
headers: {
'X-Parse-Application-Id': kParseApplicationId,
'X-Parse-REST-API-Key': kParseRestApiKey,
'Content-Type': 'application/json'
},
body: json.encode(data.toJson()),
);
return response;
}
//READ
static Future getDataList() async{
String apiUrl = _baseUrl + "Data";
Response response = await get(apiUrl, headers: {
'X-Parse-Application-Id' : kParseApplicationId,
'X-Parse-REST-API-Key' : kParseRestApiKey,
});
return response;
}
//UPDATE
static Future updateData(Data data) async{
String apiUrl = _baseUrl + "Data/${data.objectId}";
Response response = await put(apiUrl, headers: {
'X-Parse-Application-Id' : kParseApplicationId,
'X-Parse-REST-API-Key' : kParseRestApiKey,
'Content-Type' : 'application/json',
},
body: json.encode(data.toJson())
);
return response;
}
//DELETE
static Future deleteData(String objectId) async{
String apiUrl = _baseUrl + "Data/$objectId";
Response response = await delete(apiUrl, headers: {
'X-Parse-Application-Id' : kParseApplicationId,
'X-Parse-REST-API-Key' : kParseRestApiKey,
});
return response;
}
}
最佳答案
问题解决了!
我的问题是:import 'package:parse_server_sdk/parse_server_sdk.dart';
需要替换为:import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';
在 pubspec.yaml 中,只需要使用对应的依赖项:parse_server_sdk_flutter: ^2.0.1
关于android-studio - LiveQuery 不起作用,如果提供了 ParseConnectivityProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65013446/
我经常使用 SSMS 查询数据和构建数据集,我的 IT 部门负责数据库管理。 最近我发现了 Azure Data Studio,我喜欢: 智能感知 源代码控制(例如使用 Git) 来自社区的扩展 SQ
我想根据我使用的 visual studio 版本编译不同的东西,比如 #if VISUAL_STUDIO_VERSION > 2015 eventH?.Invoke(this, EventArgs.
我们的开发团队计划从 visual studio 2005 升级到 visual studio 2010 -- 跳过 visual studio 2008。 大部分项目是VB ASP.NET项目,使用
我的Visual Studio 2015无法构建2010平台工具集。它说: The build tools for Visual Studio 2010 (v100) cannot be found.
我目前正在使用 Visual Studio 2015 来编程 ASP.NET Core 应用程序。我对安装 Visual Studio 2017 有以下疑问: 什么被认为是最佳实践和/或最干净的方法?
尝试从扩展和更新获取 Visual Studio 扩展时,出现以下错误:- 向 visualstudiogallery.msdn.microsoft.com/Services/VStudio/Exte
这个问题在这里已经有了答案: Can Visual Studio Code and VS 2012 be installed on same computer? (1 个回答) 关闭去年。 在安装了
作为标准安装的一部分,Visual Studio Code 带有一个名为“Monokai Dimmed”的颜色主题。 有没有办法将它移植到 Visual Studio 2015?我检查了社区主题( h
我想开始编程 CUDA。 我已经安装了 Visual Studio 2010 Express。 我还安装了 nVidia nSight Visual Studio。 而且我具备所有常见的先决条件(Ne
Visual Studio Community Edition是否可以使用Visual Studio Online帐户上的存储库? 我一直为包含在Online帐户中的Visual Studio Onl
我有一个我一直在开发的应用程序,但在 android studio 上遇到了问题。当我点击“build->run”然后选择我的设备时,应用程序永远不会在我的手机上运行(并且自动出现的android-s
我正在使用Visual Studio2010。我面临的一个问题是,当我创建一个新的Web项目时,Visual Studio将创建该项目,并且不会在解决方案资源管理器中显示其解决方案。 另一件事是,我想
我通读了这里的许多帖子,却找不到一个有效的明确答案。因此,在花了一些时间使它生效之后,我认为应该发布它。 问题:发布配置文件将建立在服务器上,但不会发布。 解: 确保已安装Microsoft Wind
我正在尝试使用Visual Studio 2012构建针对.NET 3.5的C++ CLI应用程序。 通过安装Visual Studio 2008,并指定v90平台工具集,我已经在一台机器上进行了这项
我在 Microsoft Visual Studios 2013 中有一个项目,我想在 Microsoft Visual Studios 2010 中打开它。有什么简单的方法吗?还是我必须在2010年
我想知道,如果我发送一个解决方案文件夹(它是用 visual studio C# 编写的),您可以在 visual studio for mac 中打开解决方案吗? 在visual studio 20
有没有办法在 Visual Studio Code 和 Visual Studio 中设置相同的快捷方式(而不必每次都手动更改它们)? 例如,我在 Visual Studio Code 中经常使用 A
我刚开始了解 Visual Studio Code。我想知道,我可以将 Visual Studio 替换为所有 .NET 开发相关的工作吗? 我可以节省 Visual Studio 许可的成本吗? V
我安装了具有有效许可证(Visual Studio 订阅)的 Visual Studio 2019 企业版(VS 2019 16.1.4),它运行良好。 突然之间,当我尝试打开项目或项目中的任何文件时
我一直在使用 Compass 编译 Windows 环境中的 sass 文件,无论是在命令行上还是使用 Compass-app 来查看目录。 我刚刚开始使用 Visual Studio(专业版 201
我是一名优秀的程序员,十分优秀!