- PVSM.RU - https://www.pvsm.ru -
Эта статья является ответом на:
— Как сделать поиск пользователей по GitHub используя React + RxJS 6 + Recompose [1],
— Как сделать поиск пользователей по GitHub без React + RxJS 6 + Recompose [2],
— Как сделать поиск пользователей по Github используя VanillaJS [3].
Целью статьи является:
— показать, что на Angular тоже можно быстро написать простое приложение, хотя это не его основной конек,
— показать плюсы приложения на Angular.
Целью статьи НЕ является:
— разжиганеие очередного холивара.
Всем кому интересно прошу под кат.
Для работы с Angular [4] необходимо установить глобально angular CLI [5]
npm install -g @angular/cli
Создаем новое приложение
ng new github-ui
cd github-ui
Сразу создадим комопоненты пользователя и ошибки, и сервис для получения данных с github
ng generate component components/user
ng generate component components/error
ng generate service services/github
И подключим их в основной модуль приложения.
Так-же подключим модули HttpClient [6] (для работы с http запросами) и ReactiveForms [7] (для работы с формами).
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import { AppComponent } from './app.component';
import { UserComponent } from './components/user/user.component';
import { ErrorComponent } from './components/error/error.component';
import { GithubService } from './services/github.service';
@NgModule({
declarations: [AppComponent, UserComponent, ErrorComponent],
imports: [BrowserModule, ReactiveFormsModule, HttpClient],
providers: [GithubService],
bootstrap: [AppComponent]
})
export class AppModule {}
Т.к. Angular использует Typescript [8], а Typescript дает нам типизацию, то хорошей практикой является описывать модели данных.
Это дает следующие плсы:
— удобный автокомплит при работе с приложением,
— проверка совпадения типов на стадии компиляции,
— дает другим разработчикам понять с какими данными они работают.
export class User {
login: string;
id: number;
node_id: string;
avatar_url: string;
gravatar_id: string;
url: string;
html_url: string;
followers_url: string;
following_url: string;
gists_url: string;
starred_url: string;
subscriptions_url: string;
organizations_url: string;
repos_url: string;
events_url: string;
received_events_url: string;
type: string;
site_admin: boolean;
name: string;
company: string;
blog: string;
location: string;
email: string;
hireable: string;
bio: string;
public_repos: number;
public_gists: number;
followers: number;
following: number;
created_at: string;
updated_at: string;
}
Работу с запросами на сервер в Angular принято выносить в сервисы [9].
В созданный ранее сервис добавим метод для получения данных пользователя.
services/github.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { User } from '../models/user.model';
@Injectable()
export class GithubService {
// Подключаем модуль для работы с http
constructor(private http: HttpClient) {}
// Метод для запроса пользователя
getUser(name: string): Observable<User> {
const url = `https://api.github.com/users/${name}`;
return this.http.get<User>(url);
}
}
В Angular из коробки встроен RxJs [10]. С помощью него и модуля работы с формами мы можем подписаться на изменение значения контрола, и получить данные пользователя.
app.component.html
<div class="container"
[class.ready]="!!user">
<input [formControl]="findControl"
placeholder="GitHub username" />
<app-user *ngIf="user"
[user]="user"></app-user>
<app-error *ngIf="error"></app-error>
</div>
app.component.ts
import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { GithubService } from './services/github.service';
import { User } from './models/user.model';
import { filter, switchMap, debounceTime, catchError } from 'rxjs/operators';
import { EMPTY } from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
// Контрол для поиска пользователей
findControl = new FormControl();
// Ошибка поиска
error: boolean = false;
// Найденный пользователь
user: User = null;
// Подключение githubService для поиска пользователя
constructor(private githubService: GithubService) {}
// Хук инициализации компонента
ngOnInit() {
this.findControl.valueChanges
.pipe(
// Фильтруем если введено меньше двух символов
filter(value => value.length > 2),
// Ставим задержку одну секунду
debounceTime(1000),
// Запрашиваем данные пользователя
switchMap(value =>
this.githubService.getUser(value).pipe(
// Обработка ошибок
catchError(err => {
this.user = null;
this.error = true;
return EMPTY;
})
)
)
)
// Получение данных
.subscribe(user => {
this.user = user;
this.error = false;
});
}
}
Остальные компоненты являются «глупыми», т.е. не содержат в себе логики, а только отображают полученные данные.
<div class="github-card user-card">
<div class="header User"></div>
<a class="avatar"
[href]="'https://github.com/'+user.login">
<img [src]="user.avatar_url+'&s=80'" [alt]="user.name" />
</a>
<div class="content">
<h1>{{user.name}}</h1>
<ul class="status">
<li>
<a [href]="'https://github.com/'+user.login+'?tab=repositories'">
<strong>{{user.public_repos}}</strong>Repos
</a>
</li>
<li>
<a [href]="'https://gist.github.com/'+user.login">
<strong>{{user.public_gists}}</strong>Gists
</a>
</li>
<li>
<a [href]="'https://github.com/'+user.login+'/followers'">
<strong>{{user.followers}}</strong>Followers
</a>
</li>
</ul>
</div>
</div>
import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
import { User } from '../../models/user.model';
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class UserComponent {
@Input()
user: User;
}
<div class="error">
<h2>Oops!</h2>
<b>
User not found.
</b>
<p>Please try searching again.</p>
</div>
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-error',
templateUrl: './error.component.html',
styleUrls: ['./error.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ErrorComponent {}
— отделение получения данных от работы с ними,
— отделение шаблона от логики,
— четкая и понятная масштабируемая структура,
— встроенные модули для работы с формами и сервером,
— встроенный RxJs для ассинхронной работы,
— строгая типизация проверка на наличие ошибок при компиляции.
Как было показано выше любое приложение (особенно небольшое) можно написать используя разные библиотеки, фреймворки или чистый JS [13].
Более важным является знание инструментов которые вы используете, и понимание на сколько они подходят в данной ситуации.
Всем успехов в изучении и чистого кода!
Автор: Климент
Источник [14]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/288992
Ссылки в тексте:
[1] Как сделать поиск пользователей по GitHub используя React + RxJS 6 + Recompose: https://habr.com/post/419559/
[2] Как сделать поиск пользователей по GitHub без React + RxJS 6 + Recompose: https://habr.com/post/419653/
[3] Как сделать поиск пользователей по Github используя VanillaJS: https://habr.com/post/419893/
[4] Angular: https://angular.io/
[5] angular CLI: https://cli.angular.io/
[6] HttpClient: https://angular.io/guide/http
[7] ReactiveForms: https://angular.io/guide/reactive-forms
[8] Typescript: http://www.typescriptlang.org/
[9] сервисы: https://angular.io/tutorial/toh-pt4
[10] RxJs: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html
[11] github: https://github.com/klimentru1986/github-ui-angular
[12] live demo: https://stackblitz.com/github/klimentru1986/github-ui-angular
[13] чистый JS: http://vanilla-js.com/
[14] Источник: https://habr.com/post/419933/?utm_source=habrahabr&utm_medium=rss&utm_campaign=419933
Нажмите здесь для печати.