Flutter: Как да направя CRUD с PostgreSQL? Част 2

Днес ще споделя някои вълнуващи теми като:

  • Как да изградим RESTful api на уеб сървър, използвайки Dart и Aqueduct с интегриране на Postgresql.
  • Как да изградите мобилно приложение Flutter и да изпълнявате основни функции на CRUD с приложението Aqueduct. Вие сте тук

От предишната публикация споделих как да настроите вашия уеб сървър за прилагане на RESTful api с помощта на Aqueduct с Postgresql. В тази публикация ще започнем да изграждаме нашето приложение за развихряне, за да взаимодействаме с нашето уеб приложение.

Как да настроите Flutter проект

Създайте нов разговор за проект на Flutter flutter_crud_demo. Ако използвате Visual Studio Code, можете да създадете нов проект от View> Command Pallete> Flutter New Project> Въведете име на проекта> Изберете директория, за да запазите проекта си. Когато работното пространство се извърши инициализиране, изтрийте widget_test.dart и изпразнете съдържанието на main.dart.

Функция за четене

Бъдещ строител

Бъдещият строител ни позволява да изобразим изглед на списъка веднага след като получим списъка ни с данни асинхронно. Бъдещият строител има 2 параметъра, единият е бъдещето, който е бъдещият метод, който използваме за извличане на списъка с данни, а другият е билдер, което е какво искаме да изградим с данните. Използването на бъдещия конструктор ни позволява да покажем на потребителя CircularProgressIndicator преди данните да са готови и да показва ListView, когато е извършено извличането. В нашето тяло на скеле заменете със следния код.

тяло: нов контейнер (
  дете: нов FutureBuilder <Списък > (
    бъдеще: getAll (),
    строител: (контекст, моментна снимка) {

      ако (snapshot.hasData) {
        върнете нов ListView.builder (
          itemCount: snapshot.data.length,
          itemBuilder: (контекст, индекс) {
            върнете нова колона (
              crossAxisAlignment: CrossAxisAlignment.start,
              деца: <Джаджа> [
                нов текст (snapshot.data [индекс] .име,
                  стил: нов TextStyle (fontWeight: FontWeight.bold)),
                нов разделител ()
              ]
            );
          }
        );
      } else if (snapshot.hasError) {
        върнете нов текст ("$ {snapshot.error}");
      }

      // По подразбиране покажете зареждащ спинер
      върнете нов CircularProgressIndicator ();
    }
  ),
),

След това трябва да приложим метода getAll (), за да извлечем списък с герои от нашия уеб сървър. Нашият метод връща списък с герои от Futureof тип. Вътре във функцията извикваме и awaithttp.get (_heroesUrl). Изчакването ни позволява да изчакаме отговор, преди да преминем към следващия ред. Функцията getAll () трябва да бъде маркирана с асинхронизация, за да може да се изчаква вътре в метода. От отговора извличаме телесното съобщение и се превръщаме в наше

Бъдеще <Списък > getAll () async {
  окончателен отговор = изчакайте http.get (_heroesUrl);
  печат (response.body);
  Списък responseJson = json.decode (response.body.toString ());
  Списък  userList = createHeroesList (responseJson);
  върнете потребителски списък;
}

Трябва да импортираме някои библиотеки за някои помощни функции.

import 'dart: convert';
import 'dart: async';
import 'пакет: http / http.dart' като http;

Нека създадем герой от обаждания в клас. Този клас приема цяло число за id и низ като име.

клас герой {
  Герой ({this.id, this.name});
  final int id;
  Име на струна;
}

Вътре в клас _MyHomePageState, добавете статичен const _heroesUrl, за да съдържаме нашия localhost URL.

static const _heroesUrl = 'http: // localhost: 8888 / герои';

Нека стартираме приложението Flutter Също така не забравяйте да стартирате приложението си за уеб сървър с команда aqueduct serve.

Можем да получим списък с герои в нашето приложение Flutter

Изтриване на функция

От тук нататък ще въведем enum, който да съхранява състоянието на всяка заявка за http. Всяка http заявка трябва да върне тип HttpRequestStatus.

enum HttpRequestStatus {
  НЕ Е ГОТОВ,
  СВЪРШЕН,
  ГРЕШКА
}

се отхвърлят

Ще въведем прекарване на пръст, за да изтриете, което е много често срещан модел в мобилните приложения. За да направите това, ще заменим колона с недопустимо, както е показано по-долу. След това искаме да изтрием герой чрез неговия идентификатор в параметъра onDismissed. Методът deleteHero връща бъдеще, което е httpRequestStatus. Ако състоянието е готово, ще поискаме да пречертаем екрана с помощта на setState ().

върнете нов ListView.builder (
    itemCount: snapshot.data.length,
    itemBuilder: (контекст, индекс) {
      var item = snapshot.data [индекс];

      връщане Недопустимо (
        ключ: ключ (item.id.toString ()),
        onDismissed: (посока) async {
          httpRequestStatus = изчакайте deleteHero (item.id);
          ако (httpRequestStatus == HttpRequestStatus.DONE) {
            setState (() {
              snapshot.data.removeAt (индекс);
            });
          }
        }
        фон: контейнер (цвят: оцветен цвят),
        дете: ListTile (заглавие: Текст ('$ {item.name}')),
      );
    });

Методът deleteHero е както следва

Бъдещо deleteHero (int id) async {
  httpRequestStatus = HttpRequestStatus.NOT_DONE;
  final url = '$ _heroesUrl / $ id';
  окончателен отговор = изчакайте http.delete (url, headers: _headers);
  ако (response.statusCode == 200) {
    печат (response.body.toString ());
    httpRequestStatus = HttpRequestStatus.DONE;
  } else {
    httpRequestStatus = HttpRequestStatus.ERROR;
  }

  върнете httpRequestStatus;
}
Прекарайте пръст, за да изтриете герой

Добавяне на функция

Нека добавим икона на джаджа под AppBar, за да позволим на потребителя да добави герой.

appBar: нов AppBar (
  заглавие: нов текст („Flutter CRUD Demo“),
  действия: <Виджет> [
    IconButton (
      икона: Икона (Icons.add),
      onPress: _addHeroService,
      подсказка: „Добавяне на нов герой“,
    )
  ],
),

В _addHeroService извикваме _openDialogAddHero, за да избутаме нов екран за въвеждане на потребител от името на героя. Този метод връща ново име на герой, което ще наречем createHero с него и ако името на героя бъде успешно актуализирано, ще извикаме setState (), за да преначертаем екрана.

void _addHeroService () async {
  Име на низ = изчакайте _openDialogAddHero ();
  HttpRequestStatus httpRequestStatus = изчакайте createHero (име);
  ако (httpRequestStatus == HttpRequestStatus.DONE) {
    setState (() {
      
    });
  }
}

Нека добавим статични _stглави const за съхранение на тип HTML заглавие на съдържанието.

static final _headers = {'Content-Type': 'application / json'};

Следва кодът за изпращане на заявка за създаване на нов герой към приложението за уеб сървър.

Бъдеще createHero (име на низ) async {
  httpRequestStatus = HttpRequestStatus.NOT_DONE;
  окончателен отговор = изчакайте http.post (_heroesUrl,
      хедъри: _headers, body: json.encode ({'name': name}));
  ако (response.statusCode == 200) {
    печат (response.body.toString ());
    httpRequestStatus = HttpRequestStatus.DONE;
  } else {
    httpRequestStatus = HttpRequestStatus.ERROR;
  }

  върнете httpRequestStatus;
}
Вече можем да добавим нов герой

Функция за актуализиране

Накрая ни остава една последна функция, която е възможността да се актуализира името на героя. Искаме потребителят да докосне съществуващия герой, за да актуализира името. За това добавяме onTap вътре в ListTile, който извиква метод _updateHeroService, като предава идентификатор и име на героя в този индекс на списъка. Подобно на _addHeroService, който извлича име от изскачащия диалогов прозорец и преминава в updateHero. След това екранът се прекроява, ако updateHero е успешен.

Бъдещо _updateHeroService (int id, име на низ) async {
  String updatedName = изчакайте _openDialogUpdateHero (id, име);
  HttpRequestStatus httpRequestStatus = изчакайте актуализацияHero (id, актуализиранName);
  ако (httpRequestStatus == HttpRequestStatus.DONE) {
    печат (httpRequestStatus.toString ());
    setState (() {
      
    });
  }
}

По-долу е кодът за updateHero

Бъдеща актуализацияHero (int id, име на низ) async {
  httpRequestStatus = HttpRequestStatus.NOT_DONE;
  final url = '$ _heroesUrl / $ id';
  окончателен отговор = изчакайте http.put (URL,
      хедъри: _headers, body: json.encode ({'id': id, 'name': име}));
  ако (response.statusCode == 200) {
    печат (response.body.toString ());
    httpRequestStatus = HttpRequestStatus.DONE;
  } else {
    httpRequestStatus = HttpRequestStatus.ERROR;
  }
}
Нека разменим Хоки с Тор

Като резюме разказахме как да изградим нашето приложение за уеб сървър, изпълняващо RESTful api и успяхме да изградим Flutter приложение за изпълнение на основни функции на CRUD с PostgreSQL.

Github

https://github.com/tattwei46/flutter_crud_postgresql

Ако намерите тази статия за полезна и образователна, дайте ѝ малко да ме насърчи да напиша повече от това в бъдеще

Flutter Pub е средно издание, което ще ви донесе най-новите и невероятни ресурси като статии, видеоклипове, кодове, подкасти и т.н. за тази страхотна технология, за да ви научи как да създавате красиви приложения с нея. Можете да ни намерите във Facebook, Twitter и Medium или да научите повече за нас тук. Ще се радваме да се свържем! И ако сте писател, който се интересува да пише за нас, тогава можете да го направите чрез тези указания.