我有一个类calendar
,它可以异步读取文件。
// Copyright 2017 <Abhi Agarwal>
// Refer to LICENSE
// Dart Imports
import 'dart:async';
import 'dart:convert';
// Flutter Imports
import 'package:flutter/services.dart';
// Local Imports
import 'event.dart';
/// Class deals with the school-wide calendar Calendar.
class Calendar {
/// The days off in the year.
List<Event> daysOff = new List<Event>();
/// The half-days, not necessarily days off.
List<Event> halfDays = new List<Event>();
/// Vacations, extended days off.
List<Event> vactations = new List<Event>();
DateTime schoolStart;
DateTime schoolEnd;
DateTime schoolMaxEnd;
Calendar() {
_addDaysOff();
// _addHalfDays();
// _addVacations();
// _addTimes();
}
static const String filePath = "assets/calendar/";
/// Reads a JSON File specified by the Arguments and returns a Decoded Object.
Future<List<Map<String, String>>> _readJson(String fileName) async =>
await JSON.decode(await rootBundle.loadString(filePath + fileName));
Future _addDaysOff() async {
const String fileName = "days_off.json";
final List<Map<String, String>> parsed = await _readJson(fileName);
for (final Map<String, String> item in parsed) {
Event event = new Event(item["name"], DateTime.parse(item["date"]));
daysOff.add(event);
}
}
}
这样可以正常工作,但是当我想进行一个简单的测试时会出现问题。
// Copyright 2017 <Abhi Agarwal>
// Refer to LICENSE
import 'package:flutter/material.dart';
import 'definitions/calendar/calendar.dart';
void main() {
Calendar myCalendar = new Calendar();
runApp(new Center(child: new Text(myCalendar.daysOff[0].name)));
}
使用flutter run
,我得到RangeError (index): Invalid value: Valid value range is empty: 0
。这是有道理的,List只在初始化时才有元素。问题是,如何在数据加载之前放置占位符?
答案 0 :(得分:4)
您可以重构Calendar
课程,以展示Future
完成Calendar
准备就绪的时间:
// Private constructor, use create() to get an instance
Calendar._();
// Future that completes when the new Calendar is ready to use
static Future<Calendar> create() async {
Calendar calendar = Calendar._();
await calendar._addDaysOff();
// await calendar._addHalfDays();
// await calendar._addVacations();
// await calendar._addTimes();
return calendar;
}
然后你可以await
Future
,例如:
main() async {
Calendar myCalendar = await Calendar.create();
runApp(new Center(child: new Text(myCalendar.daysOff[0].name)));
}
如果您希望在Flutter窗口小部件树中更深处的Calendar
实例化日历,而不是让它存在,则可以等待StatefulWidget
使用FutureBuilder
进行初始化根。
答案 1 :(得分:0)
Collin Jackson 的回答对我帮助很大,但我花了一些时间来理解上下文,以便根据我的需要实施它。下面是一个更通用的示例,它使用 package com.chubb;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mongodb.MongoDbConstants;
import org.apache.tomcat.util.json.JSONParser;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.json.JSONArray;
import org.json.JSONObject;
//import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Updates;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Flow.Publisher;
import java.util.LinkedHashMap;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Expression;
import org.apache.camel.LoggingLevel;
import org.apache.camel.ProducerTemplate;
//import org.apache.camel.component.mongodb3.MongoDbConstants;
//import com.mongodb.MongoClient;
//import com.mongodb.MongoClientURI;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
//import org.json.JSONObject;
/**
* A example hellow world Camel route
*/
@Component
public class RenewalRegistryRoute extends RouteBuilder {
String KafkaOffNumber;
String mongoOffNumber;
JSONObject arry;
JSONObject arry5;
JSONObject listJson;
JSONArray arry2;
JSONObject arry3= new JSONObject();
String renewalOffer;
Bson combine;
Bson filterField;
Bson[] bodyList;
String resultListStr;
List<String> resultList;
String mongoPolicyRenewalState;
String kafkaPolicyRenewalState;
Bson msg;
Bson msg1;
String filterField2;
@Override
public void configure() throws Exception {
from("kafka:{{kafkaTopics}}?brokers={{kafkaBroker}}" + "&groupId={{TopicGroupID}}"
+ "&sslTruststoreLocation={{sslTruststoreLocation}}"
+ "&sslTruststorePassword={{sslTruststorePassword}}" + "&securityProtocol={{securityProtocol}}"
+ "&saslMechanism={{saslMechanism}}" + "&sslKeyPassword={{sslKeyPassword}}"
+ "&saslJaasConfig={{saslJaasConfig}} username=\"testuser1\" password=\"testuser1\";")
.log("kafka broker----------- {kafkaBroker} and {{kafkaBroker}}")
.log("Bodyyyyyy ${body} Headers ${headers}").process(ex -> {
Bson firstCond = null;
Bson secondCond = null;
String json = ex.getIn().getBody(String.class);
arry = new JSONObject(json);
renewalOffer = arry.getJSONObject("sourceSystemData").getString("offeringNumber");
System.out.println("********* renewalOffer:"+renewalOffer);
ex.getIn().setHeader("renewalOffern", renewalOffer);
}).log("header is = ${header.renewalOffern} ")
.setHeader(MongoDbConstants.CRITERIA, new Expression() {
public <T> T evaluate(Exchange exchange, Class<T> type) {
String renewalOffer = exchange.getIn().getHeader("renewalOffern", String.class);
System.out.println("********* Inside Evaluate renewalOffer: "+renewalOffer);
Bson equalsClause = Filters.eq("sourceSystemData.offeringNumber", renewalOffer);
System.out.println("*************equalsClause: "+equalsClause);
return exchange.getContext().getTypeConverter().convertTo(type, equalsClause);
};
})
//.setHeader(MongoDbConstants.BATCH_SIZE, constant(10))
.to("mongodb:mongoClientConnectionBean?database=renewalRegistryDB&collection=renewalShell&operation=findAll")
.marshal().json(true).process(ex -> {
resultListStr = ex.getIn().getBody(String.class);
ex.getIn().setHeader("resultListS", resultListStr);
})
.choice()
.when(header("resultListS").isEqualTo(""))
.to("mongodb:mongoClientConnectionBean?database=renewalRegistryDB&collection=renewalShell&operation=insert")
.otherwise()
.process(ex -> {
String resultListStr2=ex.getIn().getHeader("resultListS",String.class);
arry2 = new JSONArray(resultListStr2);
resultList = new ArrayList<String>();
for (int i = 0; i < arry2.length(); i++) {
resultList.add(arry2.get(i).toString());
}
ex.getIn().setHeader("result", resultList);
})
.loop(simple("${headers.result.size}"))
.process(ex->{
List<String> list = ex.getIn().getHeader("result", List.class);
String renewalRegistryMongodata = list.get(0);
listJson = new JSONObject(renewalRegistryMongodata);
mongoOffNumber= listJson.getJSONObject("sourceSystemData").getString("offeringNumber");
mongoPolicyRenewalState= listJson.getJSONObject("renewalInformation").getString("policyRenewalState");
String mongoPolicyRenewalStatus= listJson.getJSONObject("renewalInformation").getString("policyRenewalStatus");
String kafkaOffNumber = arry.getJSONObject("sourceSystemData").getString("offeringNumber");
kafkaPolicyRenewalState = arry.getJSONObject("renewalInformation").getString("policyRenewalState");
String kafkaPolicyRenewalStatus = arry.getJSONObject("renewalInformation").getString("policyRenewalStatus");
filterField = Filters.eq("sourceSystemData.offeringNumber", kafkaOffNumber);
filterField2= filterField.toString();
if(mongoPolicyRenewalState!=kafkaPolicyRenewalState) { msg =
Updates.set("renewalInformation.policyRenewalState", "CREATED3");
if(mongoPolicyRenewalStatus!=kafkaPolicyRenewalStatus) { msg1 =
Updates.set("renewalInformation.policyRenewalStatus", "SUCESS3"); } combine =
Updates.combine(msg, msg1);
from("direct:update").log("Writing to mongoDB").log("Before inserting to MongoDB")
.setBody(constant(combine)).log("The body is ${body}")
.setHeader(MongoDbConstants.CRITERIA, constant(filterField))
// .setHeader(MongoDbConstants.MULTIUPDATE, constant(true))
.removeHeaders(filterField2)
.to("mongodb:mongoClientConnectionBean?database=renewalRegistryDB&collection=renewalShell&operation=update")
.log("The returned Data is ${body} ");
});
}
}
,正如 Collin 建议的那样,并且可以直接在 DartPad
中运行。
FutureBuilder