首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >颤振:如何从api中获取数据并在PaginatedDataTable中绑定

颤振:如何从api中获取数据并在PaginatedDataTable中绑定
EN

Stack Overflow用户
提问于 2021-08-17 04:47:32
回答 1查看 1.9K关注 0票数 1
代码语言:javascript
复制
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class DataTableDemo extends StatelessWidget {
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Service History'),
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          PaginatedDataTable(
            header: Text('Service Details'),
            rowsPerPage: 4,
            columns: [
              DataColumn(label: Text('SrNo.')),
              DataColumn(label: Text('Customer Name')),
              DataColumn(label: Text('Mobile Number')),
              DataColumn(label: Text('Address')),
              DataColumn(label: Text('Company')),
              DataColumn(label: Text('Model')),
              DataColumn(label: Text('REGNo')),
            ],
            source: _DataSource(context),
          ),
        ],
      ),
    );
  }
}
 fetchSummary() async {
   
  final response = await http.get('https://api');

  if (response.statusCode == 200) {
      var parsed = json.decode(response.body);    
    List jsonResponse = parsed["Table"] as List;
    return jsonResponse.map((job) => new _Row.fromJson(job)).toList();
  } else {
    print('Error, Could not load Data.');
    throw Exception('Failed to load Data');
  }
}
class _Row {
  _Row(
    this.srNo,
    this.customerName,
    this.mobileNumber,
    this.address,
    this.company,
    this.model,
    this.rEGNo,
  );

  final int srNo;
  final String customerName;
  final String mobileNumber;
  final String address;
  final String company;
  final String model;
  final String rEGNo;

  bool selected = false;
   factory _Row.fromJson(Map<String, dynamic> json) {
    return _Row(
       json['SrNo'],
       json['CustomerName'],
       json['MobileNumber'],
        json['Address'],
        json['Company'],
        json['Model'],
        json['REGNo'],
    );
  }
}

class _DataSource extends DataTableSource {
  _DataSource(this.context) {
    _rows = 
      fetchSummary();
    
  }

  final BuildContext context;
  List<_Row> _rows;

  int _selectedCount = 0;

  @override
  DataRow getRow(int index) {
    assert(index >= 0);
    if (index >= _rows.length) return null;
    final row = _rows[index];
    return DataRow.byIndex(
      index: index,
      //selected: row.selected,
      onSelectChanged: (value) {
        if (row.selected != value) {
          _selectedCount += value ? 1 : -1;
          assert(_selectedCount >= 0);
          row.selected = value;
          notifyListeners();
        }
      },
      cells: [
        DataCell(Text(row.srNo.toString())),
        DataCell(Text(row.customerName)),
        DataCell(Text(row.mobileNumber)),
        DataCell(Text(row.address)),
        DataCell(Text(row.company)),
        DataCell(Text(row.model)),
        DataCell(Text(row.rEGNo)),
      ],
    );
  }

  @override
  int get rowCount => _rows.length;

  @override
  bool get isRowCountApproximate => false;

  @override
  int get selectedRowCount => _selectedCount;
}

我尝试过这段代码,但是绑定数据时会出错。当我从服务器调用API并获取数据(Json格式)时,无法转换数据并获得error.how,我可以转换数据并绑定到PaginatedDataTable。

源代码来自: https://material.io/components/data-tables/flutter#theming-data-tables。

EN

回答 1

Stack Overflow用户

发布于 2021-12-21 07:50:56

您需要的是一个更改通知程序。

让我们做一个简单的例子。

这是我的模型:

代码语言:javascript
复制
{
    "id":1,
    "name": "John Doe",
    "username":"johndoe",
    "email":"johndoe@mail.com",
    "address":"address",
    "phone":"1234567890",
    "website":"johndoe.com",
    "company":"johndoe pty ltd"
}

然后我的颤振数据模型将如下所示:

代码语言:javascript
复制
import 'dart:convert';

List<UserModel> userModelFromJson(String str) =>
    List<UserModel>.from(json.decode(str).map((x) => UserModel.fromJson(x)));

String userModelToJson(List<UserModel> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class UserModel {
  UserModel({
    this.id,
    this.name,
    this.username,
    this.email,
    this.address,
    this.phone,
    this.website,
    this.company,
  });

  int id;
  String name;
  String username;
  String email;
  Address address;
  String phone;
  String website;
  Company company;

  factory UserModel.fromJson(Map<String, dynamic> json) => UserModel(
        id: json["id"],
        name: json["name"],
        username: json["username"],
        email: json["email"],
        address: Address.fromJson(json["address"]),
        phone: json["phone"],
        website: json["website"],
        company: Company.fromJson(json["company"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "username": username,
        "email": email,
        "address": address.toJson(),
        "phone": phone,
        "website": website,
        "company": company.toJson(),
      };
}

接下来,我将为UserModel类创建一个数据更改通知程序:

代码语言:javascript
复制
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart' show PaginatedDataTable;

class UserDataNotifier with ChangeNotifier {
  UserDataNotifier() {
    fetchData();
  }

  List<UserModel> get userModel => _userModel;


  var _userModel = <UserModel>[]

  Future<void> fetchData() async {
    _userModel = await Api.fetchData();
    notifyListeners();
  }
}

注意,我们使用的是_userModel = await Api.fetchData();,这可以是您自己的API实现。如果您在这方面需要帮助,请查看Dio表示颤振。数据是在ChangeNotifier的init上获取的。

接下来,我们将创建一个数据源来存放所有数据:

代码语言:javascript
复制
import 'package:flutter/material.dart';

class UserDataTableSource extends DataTableSource {
  UserDataTableSource({
    @required List<UserModel> userData,
    @required this.onRowSelect,
  })  : _userData = userData,
        assert(userData != null);

  final List<UserModel> _userData;
  final OnRowSelect onRowSelect;

  @override
  DataRow getRow(int index) {
    assert(index >= 0);

    if (index >= _userData.length) {
      return null;
    }
    final _user = _userData[index];

    return DataRow.byIndex(
      index: index, // DON'T MISS THIS
      cells: <DataCell>[
        DataCell(Text('${_user.name}')),
        DataCell(Text('${_user.username}')),
        DataCell(Text('${_user.email}')),
        DataCell(Text('${_user.address}')),
        DataCell(Text('${_user.phone}')),
        DataCell(Text('${_user.website}')),
        DataCell(Text('${_user.company}')),
      ],
    );
  }

  @override
  bool get isRowCountApproximate => false;

  @override
  int get rowCount => _userData.length;

  @override
  int get selectedRowCount => 0;
  
}

最后,我们将在我们的Widget中使用此更改通知程序和DataSource:

代码语言:javascript
复制
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class DataTableScreen extends StatelessWidget {
  const DataTableScreen({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //
    return Stack(
      // scrollDirection: Axis.horizontal,
      children: [
        ChangeNotifierProvider(
            create: (_) => UserDataNotifier(),
            child: _InternalWidget()
        )
      ],
    );
  }
}

class _InternalWidget extends StatelessWidget {
  const _InternalWidget({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //
    final _provider = context.watch<UserDataNotifier>();
    final _model = _provider.userModel;

    if (_model.isEmpty) {
      return const SizedBox.shrink();
    }
    final _dtSource = UserDataTableSource(
      userData: _model,
    );

    return PaginatedDataTable(
      source: _dtSource,
      horizontalMargin: 10,
      columnSpacing: 10,
      showFirstLastButtons: true,
      rowsPerPage: PaginatedDataTable.defaultRowsPerPage,
      columns: const [
        DataColumn(
          label: Text("Name"),
        ),
        DataColumn(
          label: Text("User Name"),
        ),
        DataColumn(
          label: Text("E-mail"),
        ),
        DataColumn(
          label: Text("Address"),
        ),
        DataColumn(
          label: Text("Phone"),
        ),
        DataColumn(
          label: Text("Website"),
        ),
        DataColumn(
          label: Text("Company"),
        )
      ],
    );
  }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68811827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档