在初始化器中只能访问静态成员

时间:2019-02-11 22:23:28

标签: dart flutter

我有一个从第一个屏幕传递到第二个屏幕的int值,我可以毫无问题地获取值...我的问题是我想将接收到的值添加到astring中以完成并开始使用我的api要求添加第一个屏幕的导入值...我困在无法将其更改为静态值的接收到的int与将添加值要求为静态的api字符串之间

第二个屏幕:

let idsquery="select COLUMN_Name from ids_columns where table_id = (select table_id from ids_tables where table_name ='ZR_INVOICE_DETAILS')";

我通过共享首选项获取值,并且如果它位于Widget build(BuildContext context)内,则可以正常工作

   class CatsNews extends StatefulWidget {

    @override
    _CatsNewsState createState() => new _CatsNewsState();

    }

    class _CatsNewsState extends State<CatsNews> {
    int _id ;
    String root = "http://api.0mr.net";
    String  url = "/api/GetCategoryById/$_id";
    @override

    List data;

    Future<String> getDrawerItem() async {
    var response = await http.get(
    Uri.encodeFull(url), headers: {"Accept": "application/json"});
    setState(() {
    var respondbody = json.decode(response.body);
    data = respondbody["StoriesCategory"];
    });
    }

    Widget build(BuildContext context) {
    return Scaffold(
    appBar: AppBar(
    title: Text('Cat Screen'),
    ),
    body:  Center()

更新: 我已经将Srting网址添加到initstate()中,并且代码如下所示:

   @override
    void initState() {
    getIntPrefrence().then(updatId);
    super.initState();
    this.getDrawerItem();
    }

    void updatId(int id) {
    setState(() {
    this._id = id;
    });
    }
    }

通过将String绑定到initstate()解决了上一个问题,但是更新后的值未添加到String中,并且将导入的int id设置为null或零,但是int id可以正常工作并显示导入的Widget build(BuildContext context)内的任何Widget中的值

2 个答案:

答案 0 :(得分:0)

有问题的代码可能是

var response = await http.get(...

在上面的代码中=之后的字段初始化器中不能包含任意代码。

Dart在对象创建步骤中有严格的顺序。 字段初始化程序在构造函数初始化列表之前和超类的构造函数初始化列表之前执行。

仅在执行了所有超类的所有构造函数初始化列表之后,才会执行构造函数主体,然后才允许其访问this(正在创建您的类的实例)。

您的代码在此之前(隐式)访问this,并且此时对象未初始化,因此禁止访问this以防止未定义的行为。

静态成员可以安全访问,因为它们不依赖于对象初始化。它们完全可以在没有实例的情况下使用。

错误消息告诉您的是,初始化程序正在尝试执行此时无法完成的操作,因此您需要将代码移至其他位置。

字段初始化代码可以移到构造函数初始化列表中。如果该字段应该为final,通常可以这样做, 或构造函数主体或方法-如下所示。

var response;
@override
void initState() {
  super.initState();
  _initResponse();
}

void _initResponse() async {
  response = await http.get(
    Uri.encodeFull(url), headers: {"Accept": "application/json"});
    setState(() {
    var respondbody = json.decode(response.body);
    data = respondbody["StoriesCategory"];
  });
}

因为initState不允许async,所以我们将代码移到了从_initResponse调用的另一种方法(initState)。

答案 1 :(得分:0)

我的问题的解决方案是在方法中添加导入的值和要根据其编辑的字符串,这将启动我的api请求,如下所示:

    void initState() {
    super.initState();
    this.getDrawerItem();
    }

    Future<String> getDrawerItem() async {
    int _id ;
    String url;
    SharedPreferences pref = await
    SharedPreferences.getInstance();
    _id = (pref.getInt("id")?? 0);
    url = "http://gomhuriaonline-api.0mr."
        "net/api/GetCategoryById/$_id";
    print(url);
    response = await http
    .get(Uri.encodeFull(url), headers: 
    {"Accept": "application/json"});
    setState(() {
    var respondbody = json.decode(response.body);
    data = respondbody["StoriesCategory"];
    });
    }
    }