【问题标题】:Why DataTable Not Showing JSON in Flutter为什么 DataTable 在 Flutter 中不显示 JSON
【发布时间】:2019-05-22 23:05:33
【问题描述】:

我正在通过 json 调用构建一个 DataTable。一切顺利,但数据未显示。

//standing.dart
import '../modal/catelog_point_table_model.dart';
import '../services/category_point_table_services.dart';
import 'package:flutter/material.dart';

class DataTableWidget extends StatefulWidget {
  @override
  DataTableWidgetState createState() => DataTableWidgetState();
}

class DataTableWidgetState extends State<DataTableWidget> {
  final List<String> cityColumns = [
    'Team',
    'M',
    'W',
    'NRR',
    'Pts'
  ];
  List<City> cities;
  bool ascending;

  @override
  void initState() {
    super.initState();
    ascending = false;
  }

  @override
  Widget build(BuildContext context) {
    final width = MediaQuery.of(context).size.width;
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: SizedBox(
        width: width*1.5,
        child: ListView(
          children: <Widget>[
            buildDataTable(),
          ],
        ),
      ),
    );
  }

  Widget buildDataTable() => DataTable(
    sortAscending: ascending,
    columns: cityColumns
        .map(
          (String column) => DataColumn(
        label: Text(column),
        onSort: (int columnIndex, bool ascending) => onSortColumn(
            columnIndex: columnIndex, ascending: ascending),
      ),
    )
        .toList(),
    rows: cities.map((City city) => DataRow(
        cells: [
          DataCell(Text('${city.title}')),
          DataCell(Text('${city.price}')),
          DataCell(Text('${city.description}')),
          DataCell(Text('${city.nrr}')),
          DataCell(Text('${city.pts}')),
        ],
    ))
        .toList(),
  );

  void onSortColumn({int columnIndex, bool ascending}) {
    if (columnIndex == 0) {
      setState(() {
        if (ascending) {
          cities.sort((a, b) => a.title.compareTo(b.title));
        } else {
          cities.sort((a, b) => b.title.compareTo(a.title));
        }
        this.ascending = ascending;
      });
    }
  }
}


//catelog_point_table_model.dart

import 'dart:async' show Future;
import '../modal/catelog_point_table_model.dart';
import 'package:http/http.dart' as http;
import 'dart:async';

Future<List<City>> loadCatelog(String id) async {
  String url = 'https://icc-point-table.nittodigital.now.sh/api/Catelogs/category/5ce1a425eda9891fa8b51430';
  final response = await http.get(url);
  print(response.body);
  return cities(response.body);
}

//catelog_point_table_model.dart
import 'dart:convert';

class City {
  final int imgcount;
  final String id;
  final String title;
  final String price;
  final String description;
  final String nrr;
  final String pts;
  final List<String> gallery;

  City({
    this.imgcount,
    this.id,
    this.title,
    this.price,
    this.description,
    this.nrr,
    this.pts,
    this.gallery
  });

  factory City.fromJson(Map<String, dynamic> parsedJson) {
    var streetsFromJson  = parsedJson['gallery'];
    //print(streetsFromJson.runtimeType);
    // List<String> streetsList = new List<String>.from(streetsFromJson);
    List<String> galleryList = streetsFromJson.cast<String>();

    return new City(
      imgcount: parsedJson['img_v'],
      id: parsedJson['_id'],
      title: parsedJson['title'],
      price: parsedJson['price'],
      description: parsedJson['description'],
      nrr: parsedJson['nrr'],
      pts: parsedJson['pts'],
      gallery: galleryList,
    );
  }

}
List<City> cities(str) {
    final jsonData = json.decode(str);
    return List<City>.from(jsonData.map((x) => City.fromJson(x)));
}

NoSuchMethodError:方法“map”在 null 上被调用

这就是我得到的。也许我没有得到数据,因为 List 不是静态类型。 如果有人告诉我如何正确获取数据并与 DataRow 建立联系,那就太好了。 *对不起我糟糕的英语。

【问题讨论】:

  • 您永远不会调用loadCatelog,因此您的城市变量永远不会被初始化。
  • 是的,我明白了。我意识到并尝试初始化它。但是没有找到合适的方法。我想我必须在“initState()”里面做,对吧?你能帮我解决一下吗?

标签: flutter


【解决方案1】:

您必须从 initState 函数内部调用您的 loadCatelog。由于您的调用是异步的并且initState 不允许异步调用,因此您必须将代码放在单独的方法中:

@override
  void initState() {
    super.initState();
    ascending = false;
    _getData();
}

void _getData() async{
    cities = await loadCatelog();
}

另外,您要求 id 作为函数的参数,但永远不要使用它。因此,要么删除该参数,要么相应地传递它。

如果您只需要从 API 检索数据一次,则使用 FutureBuilder 或使用 StreamBuilder 如果您想从所述 API 获取实时更新,这将是一种更优雅的方式。

【讨论】:

  • 嗨托马斯,你是对的,但是在实施你的想法之后,它说这个错误。 “位置参数太少:需要 1 个,给定 0 个。city = await loadCatelog();”
  • 是的,因为你的方法有 id 作为参数。如果您不打算传递参数,请删除它。
  • 这应该不是问题,虽然我删除了 ID 和图库。胸围还是一样的错误。 :(
  • 如果你把Future&lt;List&lt;City&gt;&gt; loadCatelog(String id)改成Future&lt;List&lt;City&gt;&gt; loadCatelog(),用cities = await loadCatelog();调用,肯定不会再出现这个错误了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多