packages/angular_bloc/README.md
A Dart package that helps implement the BLoC pattern in AngularDart. Built to work with package:bloc.
Learn more at bloclibrary.dev!
Our top sponsors are shown below! [Become a Sponsor]
<table style="background-color: white; border: 1px solid black"> <tbody> <tr> <td align="center" style="border: 1px solid black"> <a href="https://shorebird.dev"></a> </td> <td align="center" style="border: 1px solid black"> <a href="https://getstream.io/chat/flutter/tutorial/?utm_source=Github&utm_medium=Github_Repo_Content_Ad&utm_content=Developer&utm_campaign=Github_Jan2022_FlutterChat&utm_term=bloc"></a> </td> <td align="center" style="border: 1px solid black"> <a href="https://rettelgame.com/"></a> </td> </tr> </tbody> </table>BlocPipe is an Angular pipe which helps bind Bloc state changes to the presentation layer. BlocPipe handles rendering the html element in response to new states. BlocPipe is very similar to AsyncPipe but is designed specifically for blocs.
Lets take a look at how to use BlocPipe to hook up a CounterPage html template to a CounterCubit.
counter_cubit.dartimport 'package:bloc/bloc.dart';
class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
void increment() => emit(state + 1);
void decrement() => emit(state — 1);
}
counter_page_component.dartimport 'package:angular/angular.dart';
import 'package:angular_bloc/angular_bloc.dart';
import './counter_cubit.dart';
@Component(
selector: 'counter-page',
templateUrl: 'counter_page_component.html',
pipes: [BlocPipe],
)
class CounterPageComponent implements OnInit, OnDestroy {
late final CounterCubit counterCubit;
@override
void ngOnInit() {
counterCubit = CounterCubit();
}
@override
void ngOnDestroy() {
counterCubit.close();
}
}
counter_page_component.html<div>
<h1>Counter App</h1>
<h2>Current Count: {{ $pipe.bloc(counterCubit) }}</h2>
<button (click)="counterCubit.increment()">➕</button>
<button (click)="counterCubit.decrement()">➖</button>
</div>
Lets take a look at how to use BlocPipe to hook up a CounterPage html template to a CounterBloc.
counter_bloc.dartimport 'package:bloc/bloc.dart';
sealed class CounterEvent {}
final class CounterIncrementPressed extends CounterEvent {}
final class CounterDecrementPressed extends CounterEvent {}
class CounterBloc extends Bloc<CounterEvent, int> {
CounterBloc() : super(0) {
on<CounterIncrementPressed>((event, emit) => emit(state + 1));
on<CounterDecrementPressed>((event, emit) => emit(state - 1));
}
}
counter_page_component.dartimport 'package:angular/angular.dart';
import 'package:angular_bloc/angular_bloc.dart';
import './counter_bloc.dart';
@Component(
selector: 'counter-page',
templateUrl: 'counter_page_component.html',
pipes: [BlocPipe],
)
class CounterPageComponent implements OnInit, OnDestroy {
late final CounterBloc counterBloc;
@override
void ngOnInit() {
counterBloc = CounterBloc();
}
@override
void ngOnDestroy() {
counterBloc.close();
}
void increment() => counterBloc.add(CounterIncrementPressed());
void decrement() => counterBloc.add(CounterDecrementPressed());
}
counter_page_component.html<div>
<h1>Counter App</h1>
<h2>Current Count: {{ $pipe.bloc(counterBloc) }}</h2>
<button (click)="increment()">+</button>
<button (click)="decrement()">-</button>
</div>
At this point we have successfully separated our presentational layer from our business logic layer!
CounterBloc and hook it up to an AngularDart app.bloc and angular_bloc packages.