簡體   English   中英

Flutter:如何從 api 獲取數據並在 PaginatedDataTable 中綁定

[英]Flutter: How to get data from api and bind in PaginatedDataTable

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 格式)時,無法轉換數據並出現錯誤。如何轉換我的數據並綁定到 PaginatedDataTable。

源代碼來自:[https://material.io/components/data-tables/flutter#theming-data-tables]。

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

讓我們舉一個簡單的例子。

這是我的模型:

{
    "id":1,
    "name": "John Doe",
    "username":"johndoe",
    "email":"johndoe@mail.com",
    "address":"address",
    "phone":"1234567890",
    "website":"johndoe.com",
    "company":"johndoe pty ltd"
}

那么我的顫振數據模型將如下所示:

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類創建一個數據更改通知程序:

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 for Flutter 在 ChangeNotifier 的初始化中獲取數據。

接下來,我們將創建一個數據源來容納所有數據:

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 中使用這個 Change Notifier 和 DataSource:

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"),
        )
      ],
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM