Создание hacker news с angular 2 cli, rxjs и webpack, часть 1

Создание hacker news с angular 2 cli, rxjs и webpack, часть 1
Если вы когда-либо создавали приложения с Angular 2, то знаете, что первоначальная настройка проекта отнимает немало времени. К счастью, команда Angular создала Angular CLI — утилиту командной строки, облегчающую эту задачу.

В этой статье мы построим клиента Hacker News, используя Angular CLI, RxJS Observables и Webpack как загрузчик модулей.

Готовое приложение.
Исходный код.

Создание hacker news с angular 2 cli, rxjs и webpack, часть 1
Мы постепенно, шаг за шагом, пройдём весь процесс построения приложения и я постараюсь подробно объяснять важные моменты по ходу дела, а также сделанные мной ошибки и способы их решения.

Вот краткий список того, что нам предстоит сделать:

  1. Мы начнём с построения каркаса приложения, главной страницы Hacker News
  2. Затем подключим Observable Data Service для асинхронной загрузки данных
  3. Добавим роутинг с Angular Component Router для построения навигации между страницами и видами топиков
  4. И, наконец, добавим роуты чтобы пользователь мог перейти к комментариям к топику и в профили пользователей.
Приступим

Убедитесь, что у вас установлен Node и npm, затем установите CLI в терминале:

npm install -g @angular/cli
Создадим и запустим приложение:

ng new angular2-hn
cd angular2-hn
ng serve

Откройте браузер по адресу https://localhost:4200/

Создание hacker news с angular 2 cli, rxjs и webpack, часть 1
Круто, да?

Настроим Sass как препроцессор CSS:

ng set defaults.styleExt scss
Создадим первый компонент HeaderComponent

ng generate component Header
Будет создана папка header, содержащая такие файлы:

  • header.component.scss
  • header.component.html
  • header.component.ts
  • header.component.spec.ts

Посмотрим на файл app.module.ts и увидим, что наш компонент уже задекларирован:

// app.module.ts

// ...
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';

@NgModule({
declarations: [
AppComponent,
HeaderComponent
],
//...

А взглянув в файл header.component.ts, вы увидите, что селектор компонентов — app-header. Добавим его в наш корневой компонент, app.component.ts.


Запустим приложение. Компонент header загрузился нормально:

Создание hacker news с angular 2 cli, rxjs и webpack, часть 1
Супер. Теперь добавим кое-какую разметку и стили.


Стили из файла app.component.scss можете скачать здесь. Перейдём к header.


Стили этого компонента можно скачать здесь. Запустим приложение:

Создание hacker news с angular 2 cli, rxjs и webpack, часть 1

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

Создание hacker news с angular 2 cli, rxjs и webpack, часть 1
Но у нас с края появился непредвиденный отступ. Это из-за того, что элемент body имеет отступ по-умолчанию (через margin):

Создание hacker news с angular 2 cli, rxjs и webpack, часть 1
Но если открыть app.component.scss, там указано правило margin: 0 для экранов меньше 768px:

$mobile-only: "only screen and (max-width : 768px)";

body {
margin-bottom: 0;

@media #{$mobile-only} {
margin: 0;
}
}

Так почему же оно так работает? Это из-за способа, которым Angular инкапсулирует CSS-стили компонента. Не будем вдаваться в детали, но есть три способа, которые может использовать Angular для этого:

  • None: Angular ничего не предпринимает — ни инкапсуляции, ни Shadow DOM, просто обычная загрузка стилей.
  • Emulated: Angular эмулирует поведение Shadow DOM. Это способ по-умолчанию.
  • Native: Angular использует нативный Shadow DOM браузера (только в браузерах, имеющих соответствующую поддержку).

В корневом компоненте мы добавляем стили элементу body, но оно не работает, потому что мы не указали Angular не применять никаких действий к представлению компонента:

// app.component.ts

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
selector: 'app-root',
encapsulation: ViewEncapsulation.None,
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})

export class AppComponent {
}

Перезапустим приложение и посмотрим на него. Теперь стили применились как и должно.

Создание hacker news с angular 2 cli, rxjs и webpack, часть 1

Несколько компонентов

Добавим ещё пару компонентов, Stories и Footer. Stories представляют топики в Hacker News, и мы начнём с каркаса, добавив в него упорядоченный список.

ng g component Stories
// stories.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-stories',
templateUrl: './stories.component.html',
styleUrls: ['./stories.component.scss']
})

export class StoriesComponent implements OnInit {
items: number[];

constructor() {
this.items = Array(30);
}

ngOnInit() {
}
}

  1. Story #{{i}}


Стили для Stories можно взять здесь. Подвал страницы очень простой (стили для него скачайте тут).

ng g component Footer


Обновим корневой компонент, чтобы увидеть добавленные компоненты:




Вот так теперь выглядит приложение:

Создание hacker news с angular 2 cli, rxjs и webpack, часть 1
Так как каждый топик, или элемент, будет иметь собственные атрибуты, имеет смысл создать отдельный компонент для этого.

ng g component Item
Когда у нас будут реальные данные, нужно будет передавать идентификатор элемента из компонента топиков его дочернему элементу. Тем временем, сделаем передачу позиции списка как itemID:


// item.component.ts

import { Component, Input, OnInit } from '@angular/core';

@Component({
selector: 'item',
templateUrl: './item.component.html',
styleUrls: ['./item.component.scss']
})
export class ItemComponent implements OnInit {
@Input() itemID: number;

constructor() { }

ngOnInit() {
}

}

Story #{{itemID}}


Перезапустите приложение, всё должно работать так же, а это значит, что параметр позиции передаётся успешно с @Input.

Итак, у нас получился отличный каркас главной страницы. Здесь исходный код примера на текущем этапе.

Продолжение.

Leave a Comment