Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.
In the following tutorial, we’re going to build a GitHub Search app in Flutter and AngularDart to demonstrate how we can share the data and business logic layers between the two projects.
Key Topics
BlocProvider, Flutter widget which provides a bloc to its children.
BlocBuilder, Flutter widget that handles building the widget in response to new states.
The Common GitHub Search library will contain models, the data provider, the repository, as well as the bloc that will be shared between AngularDart and Flutter.
Setup
We’ll start off by creating a new directory for our application.
We need to create a pubspec.yaml with the required dependencies.
Lastly, we need to install our dependencies.
That’s it for the project setup! Now we can get to work on building out the common_github_search package.
Github Client
The GithubClient which will be providing raw data from the GitHub API.
Let’s create github_client.dart.
Next we need to define our SearchResult and SearchResultError models.
Search Result Model
Create search_result.dart, which represents a list of SearchResultItems based on the user’s query:
Search Result Item Model
Next, we’ll create search_result_item.dart.
GitHub User Model
Next, we’ll create github_user.dart.
At this point, we have finished implementing SearchResult and its dependencies. Now we’ll move onto SearchResultError.
Search Result Error Model
Create search_result_error.dart.
Our GithubClient is finished so next we’ll move onto the GithubCache, which will be responsible for memoizing as a performance optimization.
GitHub Cache
Our GithubCache will be responsible for remembering all past queries so that we can avoid making unnecessary network requests to the GitHub API. This will also help improve our application’s performance.
Create github_cache.dart.
Now we’re ready to create our GithubRepository!
GitHub Repository
The Github Repository is responsible for creating an abstraction between the data layer (GithubClient) and the Business Logic Layer (Bloc). This is also where we’re going to put our GithubCache to use.
Create github_repository.dart.
At this point, we’ve completed the data provider layer and the repository layer so we’re ready to move on to the business logic layer.
GitHub Search Event
Our Bloc will be notified when a user has typed the name of a repository which we will represent as a TextChangedGithubSearchEvent.
Create github_search_event.dart.
Github Search State
Our presentation layer will need to have several pieces of information in order to properly lay itself out:
SearchStateEmpty- will tell the presentation layer that no input has been given by the user.
SearchStateLoading- will tell the presentation layer it has to display some sort of loading indicator.
SearchStateSuccess- will tell the presentation layer that it has data to present.
items- will be the List<SearchResultItem> which will be displayed.
SearchStateError- will tell the presentation layer that an error has occurred while fetching repositories.
error- will be the exact error that occurred.
We can now create github_search_state.dart and implement it like so.
Now that we have our Events and States implemented, we can create our GithubSearchBloc.
GitHub Search Bloc
Create github_search_bloc.dart:
Awesome! We’re all done with our common_github_search package.
The finished product should look like this.
Next, we’ll work on the Flutter implementation.
Flutter GitHub Search
Flutter Github Search will be a Flutter application which reuses the models, data providers, repositories, and blocs from common_github_search to implement Github Search.
Setup
We need to start by creating a new Flutter project in our github_search directory at the same level as common_github_search.
Next, we need to update our pubspec.yaml to include all the necessary dependencies.
Now, we need to install the dependencies.
That’s it for project setup. Since the common_github_search package contains our data layer as well as our business logic layer, all we need to build is the presentation layer.
Search Form
We’re going to need to create a form with a _SearchBar and _SearchBody widget.
_SearchBar will be responsible for taking user input.
_SearchBody will be responsible for displaying search results, loading indicators, and errors.
Let’s create search_form.dart.
Our SearchForm will be a StatelessWidget which renders the _SearchBar and _SearchBody widgets.
_SearchBar is also going to be a StatefulWidget because it will need to maintain its own TextEditingController so that we can keep track of what a user has entered as input.
_SearchBody is a StatelessWidget which will be responsible for displaying search results, errors, and loading indicators. It will be the consumer of the GithubSearchBloc.
If our state is SearchStateSuccess, we render _SearchResults which we will implement next.
_SearchResults is a StatelessWidget which takes a List<SearchResultItem> and displays them as a list of _SearchResultItems.
_SearchResultItem is a StatelessWidget and is responsible for rendering the information for a single search result. It is also responsible for handling user interaction and navigating to the repository url on a user tap.
Putting it all together
Now all that’s left to do is implement our main app in main.dart.
That’s all there is to it! We’ve now successfully implemented a GitHub search app in Flutter using the bloc and flutter_bloc packages and we’ve successfully separated our presentation layer from our business logic.
Finally, we’re going to build our AngularDart GitHub Search app.
AngularDart GitHub Search
AngularDart GitHub Search will be an AngularDart application which reuses the models, data providers, repositories, and blocs from common_github_search to implement Github Search.
Setup
We need to start by creating a new AngularDart project in our github_search directory at the same level as common_github_search.
We can then go ahead and replace the contents of pubspec.yaml with:
Search Form
Just like in our Flutter app, we’re going to need to create a SearchForm with a SearchBar and SearchBody component.
Our SearchForm component will implement OnInit and OnDestroy because it will need to create and close a GithubSearchBloc.
SearchBar will be responsible for taking user input.
SearchBody will be responsible for displaying search results, loading indicators, and errors.
Let’s create search_form_component.dart.
Our template (search_form_component.html) will look like:
Next, we’ll implement the SearchBar component.
Search Bar
SearchBar is a component which will be responsible for taking in user input and notifying the GithubSearchBloc of text changes.
Create search_bar_component.dart.
Next, we can create search_bar_component.html.
We’re done with SearchBar, now onto SearchBody.
Search Body
SearchBody is a component which will be responsible for displaying search results, errors, and loading indicators. It will be the consumer of the GithubSearchBloc.
Create search_body_component.dart.
Create search_body_component.html.
If our state isSuccess, we render SearchResults. We will implement it next.
Search Results
SearchResults is a component which takes a List<SearchResultItem> and displays them as a list of SearchResultItems.
Create search_results_component.dart.
Next up we’ll create search_results_component.html.
It’s time to implement SearchResultItem.
Search Result Item
SearchResultItem is a component that is responsible for rendering the information for a single search result. It is also responsible for handling user interaction and navigating to the repository url on a user tap.
Create search_result_item_component.dart.
and the corresponding template in search_result_item_component.html.
Putting it all together
We have all of our components and now it’s time to put them all together in our app_component.dart.
That’s all there is to it! We’ve now successfully implemented a GitHub search app in AngularDart using the bloc and angular_bloc packages and we’ve successfully separated our presentation layer from our business logic.
In this tutorial we created a Flutter and AngularDart app while sharing all of the models, data providers, and blocs between the two.
The only thing we actually had to write twice was the presentation layer (UI) which is awesome in terms of efficiency and development speed. In addition, it’s fairly common for web apps and mobile apps to have different user experiences and styles and this approach really demonstrates how easy it is to build two apps that look totally different but share the same data and business logic layers.