Если сразу после Руководства по работе с несколькими компонентами, если на изучение Служб уходит неделя, то это руководство для вас. Здесь особо нечего делать, просто рефакторинг документации служб для облегчения понимания. Я бы не хотел, чтобы кто-то еще испытывал стресс от понимания сервисов в angular dart.

Давайте начнем.

Создание нескольких компонентов для обработки различных операций в приложении angular делает ваш код аккуратным и плавным. Но во время этого процесса всем этим компонентам требуется доступ к данным или информации, которые необходимы для работы вашего приложения (какое приложение без данных).

Создание одних и тех же данных в разных компонентах не кажется эффективным для Angular-разработчика, поэтому сервисы кажутся вполне подходящими. Это ваш билет в один конец к джекпоту.

Служба просто обрабатывает все данные, необходимые вашему приложению в классе. Вместо того, чтобы создавать одни и те же данные повсюду, вы можете просто получить к ним доступ из одного класса, что снижает вероятность возникновения ошибок.

Класс обслуживания работает аналогично внедрению зависимостей.

Вернемся к нашему туру по рассказам героев, мы продолжим с кода мастер / детали. Давайте посмотрим, как мы сможем достаточно хорошо понять и внедрить сервисы. Мы будем взаимодействовать всего с двумя классами:

· Hero_service.dart

· App_component.dart

Наш класс AppComponent выглядит так:

class AppComponent {
final title = “Tour of Heroes”;
//initialize a variable name of type class hero called selected
Hero selected;
//Imported mock heroes class and assigned the value to a list of type hero which is a class
List<Hero> heroes = mockHeroes;
//handling on select event
void onSelect(hero) => selected = hero;
}

Наши данные Hero, состоящие из всего списка героев, хранятся в классе с именем mock_heroes, присвоенном имени переменной mockHeroes.

В преддверии дальнейшего развития нашего приложения Tour of Hero мы создадим нашу панель управления, отдельное представление для редактирования данных о героях, и пользователи также смогут выбирать героев из списка. Все эти разработки будут разделены на компоненты, которым также потребуется доступ к данным героя.

Во-вторых, чтобы добиться гибкости в нашем приложении, мы собираемся создать папку с именем service в нашей папке lib, и в этой служебной папке мы создадим инъекционный файл dart HeroService с именем hero_service.dart; Двигаясь дальше, мы перемещаем все наши данные о героях в этот класс и делимся этой службой со всеми компонентами, которым нужен доступ к этим данным.

В нашем файле hero_service мы собираемся создать класс HeroService:

class HeroService{
}

Теперь давайте сделаем так, чтобы сервис-герой получал доступ к данным из веб-сервиса, локального хранилища или базы данных. Но в этом случае мы имеем дело с данными о героях, которые хранятся в нашем файле дротика mock_heroes, который состоит из списка героев. Мы импортируем наш файл mock_heroes и возвращаем все данные mockHeroes с помощью метода getAllHeroes ().

import ‘package:angular_app/src/hero.dart’;
import ‘package:angular_app/src/mock_heroes.dart’;
class HeroService{
List<Hero> getAllHeroes() => mockHeroes;
}

Список ‹Hero› - это просто объявление, определяющее тип данных.

Ага, просто наш герой сервис жив. Теперь давайте воспользуемся службой героя, созданной в компоненте, которому требуется доступ к данным героя, и которым в данном случае является компонент приложения.

Вернувшись к нашему файлу AppComponent.dart, мы импортируем файл службы героя, и поскольку это класс, наша интуиция подсказывает нам, что позволяет создать экземпляр класса службы героя, но мы этого не делаем. t создать экземпляр службы по следующим причинам, которые вы можете найти здесь.

Чтобы создать экземпляр службы, то есть службы героя, мы объявляем имя частной переменной heroService типа HeroService, затем добавляем конструктор, инициализирующий частная собственность в нашем компоненте приложения.

class AppComponent {
final title = “Tour of Heroes”;
final HeroService _heroService;
AppComponent(this._heroService);
//initialize a variable name of type class hero called selected
Hero selected;
//Imported mock heroes class and assigned the value to a list of type hero which is a class
List<Hero> heroes = mockHeroes;
//handling on select event
void onSelect(hero) => selected = hero;
}

Теперь мы хотим, чтобы angular создал новый экземпляр службы героя, и единственный способ сделать это - добавить это свойство в наш блок @Component:

providers: [ClassProvider(HeroService)],

Вот и все; мы закончили предоставлять доступ к данным героя из нашего класса компонентов приложения. Итак, давайте воспользуемся этим сервисом, чтобы показать нужные нам данные.

Во-первых, мы хотим заполучить всех героев. При этом мы избавляемся от инициализированных героев, которые извлекают данные из класса mockHeroes.

List<Hero> heroes = mockHeroes;

И просто объявите имя переменной героями типа List ‹Hero›.

List<Hero> heroes;

Кроме того, мы добавляем частный метод _getHeroes () к компоненту приложения и назначаем всех героев, извлеченных с помощью getAllHeroes () из нашего сервиса к переменной с именем heroes.

void _getHeroes(){
heroes = _heroService.getAllHeroes();
}

Наш код выглядит вполне правильным, но не полным для отображения нужных нам данных. Метод _getHeroes () просто сидит, angular знает о его существовании, но не совсем уверен, как его использовать. Чтобы использовать метод _getHeroes (), мы реализуем ловушку жизненного цикла ngOnInit.

Класс AppComponent реализует OnInit, и в наш код мы добавляем метод ngOnInit () с логикой инициализации. Это просто то, что при загрузке приложения Angular вызывает логику, инициализированную внутри него. Мы не получаем данные из конструктора AppComponent, поэтому мы не передаем метод getAllHeroes () в AppComponent конструктор. Между тем, ngOnInit - хорошее место для компонента, чтобы получить свои начальные данные, особенно при выполнении запросов. Подробнее о ngOnInit здесь.

Хорошо, давайте реализуем интерфейс OnInit и добавим нашу логику в метод ngOnInit ().

class AppComponent implements OnInit{
final title = “Tour of Heroes”;
final HeroService _heroService;
AppComponent(this._heroService);
//initialize a variable name of type class hero called selected
Hero selected;
//Imported mock heroes class and assigned the value to a list of type hero which is a class
List<Hero> heroes;
void ngOnInit() => _getHeroes();
void _getHeroes(){
heroes = _heroService.getAllHeroes();
}
//handling on select event
void onSelect(hero) => selected = hero;
}

С этим наш код работает нормально, но есть еще кое-что, на что мы не учли, и что это могло быть?

Давай возьмем перерыв.

Мы вернулись. Мы не учли то, что сделали базовое предположение, что наши данные будут предоставлены пользователю довольно быстро, но это не тот случай, когда данные извлекаются с удаленного сервера. Основываясь на этом руководстве, это действительно хорошо работает локально, потому что наши данные находятся прямо в приложении, их легко получить и быстро отобразить, как ракета.

Теперь мы не хотим, чтобы наши пользователи продолжали ждать, пытаясь получить данные, отсюда и необходимость в асинхронных сервисах. Для решения этой проблемы мы собираемся использовать Future, асинхронный метод, изменяющий работу getAllHeroes ().

Чтобы вернуть будущее, наша служба сама должна вернуть будущее. В нашем классе обслуживания мы импортируем 'dart: async', потому что он определяет будущее и обновляет класс HeroService с помощью будущего, возвращающего getAllHeroes ().

import ‘package:angular_app/src/hero.dart’;
import ‘package:angular_app/src/mock_heroes.dart’;
import ‘dart:async’;
class HeroService{
Future<List<Hero>> getAllHeroes() async => mockHeroes;
}

С этими изменениями данные о наших героях становятся доступными немедленно.

Теперь наш сервис-герой возвращает будущее, но мы не обработали будущее в нашем компоненте приложения, когда оно завершилось. Основываясь на документации Angular dart, есть разные методы для достижения этого, но я предпочитаю метод async / await, который проще реализовать.

Мы просто переписываем метод _getHeroes () для обработки будущего:

Future<void> _getHeroes() async{
heroes = await _heroService.getAllHeroes();
}

Таким образом, наш метод _getHeroes () выглядит так. Убедитесь, что вы также импортируете dart: async в компонент приложения, и все.

Мы полностью проработали сервисы для нашего приложения «Тур героев». Код компонента нашего приложения в конечном итоге будет выглядеть так:

import ‘package:angular/angular.dart’;
import ‘package:angular_forms/angular_forms.dart’;
import ‘package:angular_components/angular_components.dart’;
import ‘service/hero_service.dart’;
import ‘src/hero.dart’;
import ‘src/mock_heroes.dart’;
import ‘dart:async’;
@Component(
selector: ‘my-app’,
templateUrl: ‘app_component.html’,
styleUrls: [‘app_component.css’],
directives: [coreDirectives,formDirectives],
providers: [ClassProvider(HeroService)],
)
class AppComponent implements OnInit{
final title = “Tour of Heroes”;
final HeroService _heroService;
AppComponent(this._heroService);
//initialize a variable name of type class hero called selected
Hero selected;
//Imported mock heroes class and assigned the value to a list of type hero which is a class
List<Hero> heroes;
void ngOnInit() => _getHeroes();
Future<void> _getHeroes() async{
heroes = await _heroService.getAllHeroes();
}
//handling on select event
void onSelect(hero) => selected = hero;
}

И наша сказка Путешествие героя работает отлично. Рывком на прогулку.