CHAPTER 2. Your First Angular App

Angular CLI

npm install --global @angular/cli

Creating the Project

ng new todo

Adding the Bootstrap CSS Package

npm install bootstrap

CHAPTER 7. SportsStore: A Real Application

Path

/mnt/disk2/home/egor/prog/ng-lists/books/

File

src/app/app.component.html

Adding the CSS Style Sheets to the Application

ng add @ng-bootstrap/ng-bootstrap

npm install ngx-markdown --save
Listing 7-1. Adding CSS to the angular.json file in the SportsStore Folder
      ...
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/SportsStore",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.css",
              "node_modules/bootstrap/dist/css/bootstrap.min.css", (1)
              "node_modules/font-awesome/css/font-awesome.min.css" (2)
            ],
            "scripts": []
          },
          ...
npm install bootstrap --save
npm install font-awesome --save

Preparing the HTML File

Listing 7-5. Preparing the index.html File in the src Folder
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>SportsStore</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body class="m-2"> (1)
  <app>SportsStore Will Go Here</app>
</body>
</html>

Starting the Data Model

Creating the Model Repository

Listing 7-11
import { Injectable } from "@angular/core";
import { Product } from "./product.model";
import { StaticDataSource } from "./static.datasource";

@Injectable()
export class ProductRepository {

    private products: Product[] = [];
    private categories: string[] = [];

    constructor(private dataSource: StaticDataSource) {
        dataSource.getProducts().subscribe(data => {
            this.products = data;
            this.categories = data
                .map(p => p.category)
                .filter((c, index, array) => array.indexOf(c) == index).sort(); (1)
        });
    }

    getProducts(category: string = null): Product[] { (2)
        return this.products
            .filter(p =>
                category == null ||
                category == p.category);
    }

    getProduct(id: number): Product {
        return this.products.find(p => (3)
            p.id == id);
    }

    getCategories(): string[] {
        return this.categories;
    }
}
1 array.indexOf выдает индекс первого вхождения, то есть таким образом удаляются дубликаты
2 Для параметра null возвращается весь список
3 В этом фрагменте используются методы массива map, filter, find

Starting the Store

Creating the Store Component and Template

  • store.component.ts

  • store.component.html

CHAPTER 23. Using Reactive Extensions

import { Component, Inject } from "@angular/core";
import { NgForm } from "@angular/forms";
import { Product } from "../model/product.model";
import { Model } from "../model/repository.model";
import { MODES, SharedState, SHARED_STATE } from "./sharedState.model";
import { Observable } from "rxjs";
import { filter, map, distinctUntilChanged, skipWhile } from "rxjs/operators";

@Component({
    selector: "paForm",
    templateUrl: "form.component.html",
    styleUrls: ["form.component.css"]
})
export class FormComponent {
    product: Product = new Product();

    constructor(private model: Model,
        @Inject(SHARED_STATE) private stateEvents: Observable<SharedState>) {
            stateEvents
            .pipe(skipWhile(state => state.mode == MODES.EDIT))
            .pipe(distinctUntilChanged((firstState, secondState) =>
                firstState.mode == secondState.mode
                    && firstState.id == secondState.id))
            .subscribe(update => {
                this.product = new Product();
                if (update.id != undefined) {
                    Object.assign(this.product, this.model.getProduct(update.id));
                }
                this.editing = update.mode == MODES.EDIT;
            });
    }

    editing: boolean = false;

    submitForm(form: NgForm) {
        if (form.valid) {
            this.model.saveProduct(this.product);
            this.product = new Product();
            form.reset();
        }
    }

    resetForm() {
        this.product = new Product();
    }
}