Запчасти на dyna / toyoace в кузове xzu346

Работа с компонентами

Последнее обновление: 09.02.2020

Кроме основных компонентов в приложении мы также можем определять какие-то вспомогательные компоненты, которые управляют каким-то участком разметки
html. Более того в приложении на странице может быть ряд разных блоков с какой-то определенной задачей. И для каждого такого блока можно создать отдельный компонент, чтобы упростить управление блоками на странице.

Добавим в проект второй компонент. Для этого добавим в папку src/app новый файл child.component.ts. В итоге весь проект будет выглядеть следующим образом:

Определим в файле child.component.ts следующий код:

import { Component } from '@angular/core';
     
@Component({
    selector: 'child-comp',
    template: `

Добро пожаловать {{name}}!

`,
styles:
})
export class ChildComponent {
name= «Евгений»;
}

Здесь определен класс ChildComponent. Опять же чтобы сделать этот класс компонентом, необходимо применить декоратор .

Компонент будет управлять разметкой html, которая будет вставляться в элемент .

Шаблон представления будет просто выводить заголовок. В заголовке выводится имя, заданное через переменную name.

И кроме того, здесь определены стили для элементов h2 и p.

Теперь изменим код компонента AppComponent в файле app.component.ts:

import { Component } from '@angular/core';
     
@Component({
    selector: 'my-app',
    template: `

Привет {{name}}

`,
styles:
})
export class AppComponent {
name = ‘Петр’;
}

Это основной компонент, который будет запускаться при запуске приложения, и через него мы будем использовать остальные компоненты. Так,
компонент ChildComponent будет загружаться в элемент . И в шаблоне компонента AppComponent как раз определен такой элемент.

Кроме того, компонент определяет стили для тех же элементов на странице, и также, как и ChildComponent, определяет свойство name, только с другим значением.

Чтобы использовать все определенные в проекте компоненты, они должны быть указаны в главном модуле приложения. Определим в файле
app.module.ts следующий модуль:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule }   from '@angular/forms';
import { AppComponent }   from './app.component';
import { ChildComponent }   from './child.component';
@NgModule({
    imports:      ,
    declarations: ,
    bootstrap:    
})
export class AppModule { }

Запустим проект:

Результат показывает, что несмотря на то, что один компонент как бы включен в другой с помощью тега , но тем не менее стили
одного компонента не применяются к другому. Каждый компонент очерчивает свою область с помощью шаблона, свое представление, которым он и управляет.

Также каждый компонент использует свое значение свойства name. То есть компоненты фактически существуют относительно независимо.

ng-content

Элемент позволяет внедрять родительским компонентам код html в дочерние компоненты. Так, изменим компонент ChildComponent
следующим образом:

import { Component } from '@angular/core';
     
@Component({
    selector: 'child-comp',
    template: `

Привет {{name}}

`,
styles:
})
export class ChildComponent {
name= «Евгений»;
}

Вместо элемента извне можно будет передать любое содержимое.

И изменим код главного компонента AppComponent:

import { Component } from '@angular/core';
     
@Component({
    selector: 'my-app',
    template: `

Добро пожаловать {{name}}!

`,
styles:
})
export class AppComponent {
name = ‘Tom’;
}

В элемент здесь передается заголовок .
Затем этот заголовок будет вставляться в дочерний компонент ChildComponent на место :

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

Examples

Defining a model

module('myApp', ); // Add "ActiveRecord" as module dependency.

module('myApp').factory('Task', function (ActiveRecord) {

   return ActiveRecord.extend({

   	// Rest API configuration for retrieving and saving tasks.
   	$urlRoot '/api/tasks',

   	// Optional defaults
   	$defaults {
   		title 'Untitled',
   		estimate ''
   	},

   	// optional named constructor (Shows "Task" as the type in a console.log)
   	$constructor function Task(properties) {
   		this.$initialize.apply(this, arguments)
   	},

   	// An example method for task instances
   	/**
   	 * Return the estimate in hours
   	 * @return {Number}
   	 */
   	estimateInHours function () {
   		var value = parseFloat(this.estimate);
   		if (isNaN(value)) {
   			return 0.0;
   		}
   		return value  3600;
   	}
   });

Fetching and saving data.

module('myApp').controller('TaskCtrl', function ($scope, Task, $document) {

	Task.fetchOne(7).then(function (task7) { // Fetches '/api/tasks/7'
		$scope.task = task7;
		$document.title = task7.title  + ' - MyApp';
	});

	/**
	 * @param {Task} task
	 */
	$scope.saveTask = function (task) {
		$scope.spinnerVisible = true;
		task.$save().then(function () {
			$scope.successVisible = true;
		}).catch(function (error) {
			$scope.error = error;
		}).finally(function () {
			$scope.spinnerVisible = false;
		});
	};
});

Loading models via ngRoute

module('myApp', ).config(function ($routeProvider) {
	$routeProvider
		.when('/tasks', {
			templateUrl 'tasks.html',
			controller 'TaskListCtrl',
			resolve {
				tasks function (Task) {
					return Task.fetchAll();
				}
			}
		})
		.when('/tasks/:taskId', {
			templateUrl 'task.html',
			controller 'TaskCtrl',
			resolve {
				task function ($routeParams, Task) {
					return Task.fetchOne($routeParams.taskId);
				}
			}
		});
});

module('myApp').controller('TaskCtrl', function ($scope, task) {
	$scope.task = task;
});

Differences compared to Backbone.Model

  • No attributes property.
  • Because the properties and methods are on the same level the ActiveRecord methods & config-properties are prefixed with «$» to prevent naming collisions.
  • Stripped out functionality that is provided by angular)
    • No getter/setter methods. (Angular has $scope.$watch)
    • No event system. (Angular has $scope.$emit)
    • No dependency on underscore. (angular.extend, angular.isFunction, etc)
    • No dependency on jQuery. (Angular has $http)
    • No Collection class. (Angular works with plain javascript array’s)
  • Added static fetchOne(id) and fetchAll() class-methods.
  • Added read & write filtering of properties through angular filters.

angular.json¶

Следующий шаг после установки Angular и изучения структуры «скелета» приложения — настройка. — главный конфигурационный файл так называемого Angular Workspace (директория my-app), сгенерированного с использованием и объединяющего в себе множество проектов (само приложение и созданные библиотеки для него).

Основные свойства:

  • — версия Angular Workspace;
  • — указывает, где будут располагаться внутренние приложения и библиотеки, по умолчанию projects;
  • — описание конфигураций для каждого из элементов Angular Workspace. По умолчанию вместе с основным генерируется проект с интеграционными тестами. Опции:
  • — определяет директорию с файлами, включая конфигурационные, всего проекта;
  • — определяет директорию с исходными файлами;
  • — тип проекта, может быть только или ;
  • — префикс, который будет использоваться при именовании компонентов и директив;
  • — позволяет задавать отличную от по умолчанию конфигурацию сущностей Angular, например, можно для всех создаваемых компонентов переопределить работу механизма Change Detection;
  • — используется для настройки запуска или сборки.
  • — имя проекта, который будет использоваться при использовании команд Angular CLI (по умолчанию основной).

Рассмотрим подробно в параметр свойства . Здесь нас интересуют и .

В указываются следующие опции:

  • — путь, где будет находиться «собранный» проект (подробно о сборке здесь);
  • — путь к ;
  • — путь к ;
  • — путь к ;
  • — путь к ;
  • — массив с указанием путей к статическому контенту, могут быть папки или отдельные файлы;
  • — массив с указанием путей к стилям, причем стили распространяются на все приложение;
  • — массив с указанием путей к javascript-файлам, обычно здесь подключаются сторонние библиотеки, не являющиеся модулями Angular, например, jQuery.

Всегда подключайте сторонние скрипты и стили не в , а в .

В указываются настройки, связанные со средой окружения (environment, далее СО) работы приложения.

Каждое свойство объекта — название СО с объектом настроек среды в качестве значения.

СО указывается при запуске (сборке) в качестве параметра (краткая запись ).

В объекте настроек СО множество параметров, назначение большинства которых понятно из их названия. Остановимся на .

В директории по умолчанию находятся два файла: и . В них указываются параметры, зависящие от СО, например, адрес сервера, с которого будут запрашиваться данные. По умолчанию используется .

Объект, используемый в качестве значения , позволяет переопределить источник для указанной СО.

Можете открыть и найти соответствующий код.

Overview

The AngularJS framework works by first reading the Hypertext Markup Language (HTML) page, which has an additional custom HTML attributes embedded into it. Angular interprets those attributes as directives to bind input or output parts of the page to a model that is represented by standard JavaScript variables. The values of those JavaScript variables can be manually set within the code, or retrieved from static or dynamic JSON resources.

AngularJS is built on the belief that declarative programming should be used to create user interfaces and connect software components, while imperative programming is better suited to defining an application’s business logic. The framework adapts and extends traditional HTML to present dynamic content through two-way data-binding that allows for the automatic synchronization of models and views. As a result, AngularJS de-emphasizes explicit Document Object Model (DOM) manipulation with the goal of improving testability and performance.

AngularJS’s design goals include:

  • to decouple DOM manipulation from application logic. The difficulty of this is dramatically affected by the way the code is structured.
  • to decouple the client side of an application from the server-side. This allows development work to progress in parallel and allows for reuse of both sides.
  • to provide structure for the journey of building an application: from designing the UI, through writing the business logic, to testing.

AngularJS implements the MVC pattern to separate presentation, data, and logic components. Using dependency injection, Angular brings traditionally server-side services, such as view-dependent controllers, to client-side web applications. Consequently, much of the burden on the server can be reduced.

Модуль FormsModule и директива NgModel

Последнее обновление: 10.02.2020

Для взаимодействия с пользователем в веб-приложениях, как правило применяются формы. В Angular прежде чем использовать формы в компонентах, нам надо
импортировать в главном модуле AppModule модуль FormsModule, который позволяет работать с формами:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent }   from './app.component';

import { FormsModule }   from '@angular/forms';

@NgModule({
    imports:      ,
    declarations: ,
    bootstrap:    
})
export class AppModule { }

Кроме того, в файле конфигурации приложения package.json среди списка используемых зависимостей должен быть указан пакет «angular/forms»:

{
    "name": "helloapp",
    "version": "1.0.0",
    "description": "First Angular 9 Project",
    "author": "Eugene Popov metanit.com",
    "scripts": {
        // команды angular cli
    },
    "dependencies": {
        "@angular/forms": "~9.0.0",
		// остальные пакеты
    },
    "devDependencies": {
        
		// остальные пакеты
    }
}

При работе с формами ключевым моментом является использование директивы NgModel.
Эта директива с помощью переданной модели создает объект и привязывает эту модель к созданному элементу формы.
Объект FormControl отслеживает значение модели, а также отвечает за валидацию этого значения и взаимодействие с пользователем.

Данная директива принимает переданную ей модель в качестве входного свойства. Причем мы можем использовать как однонаправленную, так и двунаправленную привязку.

Если нам надо просто вывести значение модели в поле ввода, то можно ограничиться и однонаправленной привязкой:

Это обычная привязка свойства, где в качестве модели используется некоторое свойство title, определенное в классе компонента.

Если нам надо отслеживать изменение введенных данных, то мы можем использовать двунаправленную привязку:

Рассмотрим применение NgModel на примере. Возьмем проект с базовой структурой:

Определим в файле app.component.ts следующий компонент:

import { Component} from '@angular/core';
        
export class Phone{
	constructor(public title: string, 
				public price: number, 
				public company: string)
	{ }
}

@Component({
    selector: 'my-app',
    template: ` 
					
					
					
					
			  
			  

Добавленные элементы

{{p.title}} ({{p.company}}) — {{p.price}}

`
})
export class AppComponent {

title: string;
price: number;
company: string;

phones: Phone[] = [];
companies: string[] = ;

addPhone(){
this.phones.push(new Phone(this.title, this.price, this.company));
}
}

Для представления данных здесь определен класс Phone, в котором есть три свойства. Класс компонента содержит массив объектов Phone. С помощью метода
в этот массив добавляется новый объект.

Для добавления данных в шаблоне определены три поля ввода. В каждом поле определены директивы типа . Тем самым фактически определяются
некоторые значения, которые привязаны к этим полям. В обработчике нажатия кнопки вызывается метод , в который передаются эти значения.

В конце шаблона добавленные данные из массива phones выводятся на страницу:

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

import { Component} from '@angular/core';
	  
export class Phone{
	constructor(public title: string, 
				public price: number, 
				public company: string)
	{ }
}

@Component({
    selector: 'my-app',
    template: ` 
					
					
					
					
			  
			  

Добавленные элементы

{{p.title}} ({{p.company}}) — {{p.price}}

`
})
export class AppComponent {

phone: Phone = new Phone(«», 0, «Huawei»);
phones: Phone[] = [];
companies: string[] = ;

addPhone(){
this.phones.push(new Phone(this.phone.title, this.phone.price, this.phone.company));
}
}

Для полей ввода здесь создана отдельная переменная phone, к свойствам которой привязаны поля ввода

Стоит также обратить внимание на то, как добавляется новый
объект в массив phones — здесь не добавляется напрямую переменная phone, а создается отдельный объект, который инициализируется значениями из переменной phone. А в остальном результат будет тем же, что и в предыдущем примере

НазадВперед

Изменения делаются чистыми функциями

Операция, инициируемая отправкой действия, будет чистой функцией, называемой в архитектуре — (редукторами).

Эти редукторы (просто чистые функции) получают действие () и состояние (), в зависимости от отправленного действия (обычно отфильтрованного оператором ), они выполняют операцию и возвращают новый объект состояния.

Преимущества использования чистых функций хорошо известны, например то что они сразу готовы к тестированию. Если вы передадите те же аргументы, то получите тот же результат.

Этот подход также позволяет нам перемещаться между различными экземплярами нашего состояния с помощью инструментов разработки и видеть, что изменилось между экземплярами, кто их изменил, и многое другое. Поэтому использование чистых функций и возвращение новых экземпляров состояния также значительно облегчает отладку.

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

Директива¶

Предназначение директив — преобразование DOM заданным образом, наделение элемента поведением.

По своей реализации директивы практически идентичны компонентам, компонент — это директива с HTML-шаблоном, но с концептуальной точки зрения они различны.

Есть два вида директив:

  • структурные — добавляют, удаляют или заменяют элементы в DOM;
  • атрибуты — задают элементу другое поведение.

Они создаются с помощью декоратора с конфигурационным объектом.

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

Каждому из блоков архитектуры Angular посвящена отдельная глава, где все подробно расписано и показано на примерах.

reaction

Aside from autorun, MobX allows you to react to specific data changes.

Usage:

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

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    {{ parity }}


`
})
class AppComponent {
  getParity() {
    return this.parity = store.counter % 2 ? 'Odd'  'Even';
  }
}

The function will automatically re-run whenever any observable that it uses changes.
Change Detection will run automatically whenever the return value of changes.
If you don’t return anything, change detection will not run.

In this example, the property will be updated according to ,
and change detection will run only when the changes.

Обработка ошибок

Последнее обновление: 11.02.2020

При работе с сетью и http нередко могут происходить ошибки, например, в момент запроса сеть стала недоступна, неправильно указан адрес и соответственно не найден
ресурс, либо доступ к ресурсу ограничен, либо другие ошибки. Перехват ошибок позволит выяснить проблему и каким-то образом обработать их, например,
вывести пользователю сообщение об ошибке.

Например, изменим код компонента AppComponent:

import { Component, OnInit} from '@angular/core';
import { HttpService} from './http.service';
import {User} from './user';
  
@Component({
    selector: 'my-app',
    template: `{{error}}
                

Имя пользователя: {{user?.name}}
Возраст пользователя: {{user?.age}}

Метод в качестве второго параметра принимает обработчик, который вызывается в случае возникновения ошибки.
В этом обработчике мы можем получить ошибку и обработать ее. Ошибка собственно представляет объект, из которого мы можем получить ряд данных. В частности,
свойство message позволяет получить сообщение об ошибке, а свойство status — статусный код ответа.
И в данном случае в компоненте определена переменная для хранения сообщения об ошибке. И в шаблоне эта переменная выводится
на веб-страницу. И например, при обащении к несуществующему файлу json мы получим следующую ошибку:

Кроме того, для перехвата ошибок к объекту Observable, который является результатом запроса, можно использовать функцию . Так,
возьмем код сервиса из прошлой темы и добавим к нему обработку ошибок:

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {User} from './user';
import {Observable, throwError} from 'rxjs';
import { map, catchError} from 'rxjs/operators';
  
@Injectable()
export class HttpService{
  
    constructor(private http: HttpClient){ }
      
    getUsers() : Observable {
        return this.http.get('usersP.json').pipe(map(data=>{
            let userList = data;
            return userList.map(function(user:any) {
                return {name: user.userName, age: user.userAge};
              });
        }),
        catchError(err => {  
            console.log(err); 
            return throwError(err);
        }))
    };
}

Для имитации исключения здесь передается заведомо несуществующий адрес «usersP.json». Для обработки ошибок в метод передается
в качестве второго параметра функция для обработки ошибок. В качестве подобной функции используется функция catchError().
Она принимает объект ошибки, который затем выводится на консоль. С помощью вывода на консоль мы можем исследовать объект. Это тот же объект, который
мы выше получаем в AppComponent в методе subscribe. С помощью метода throwError() возвращается результат — новый объект
Observable, который содержит информацию об ошибке.

НазадВперед

Настроить всё вместе

Отлично, мы создали всё, что нужно нашему хранилищу, но нам пока не хватает одной вещи — собрать всё воедино. Я собираюсь сделать это в модуле , но вы можете применить то же самое в модуле вашего приложения.

Давайте посмотрим модуль приложения:

Файл с описанием модуля приложения

Давайте перечислим то, что необходимо для настройки нашего хранилища:

  1. Мы импортируем наши редукторы, и передаём их в метод модуля хранилища.
  2. Мы импортируем наши эффекты, и передаём их внутри массива в метод модуля эффектов.
  3. Мы передаём настройки для модуля состояния маршрутизатора .
  4. И мы добавляем инструменты разработчика хранилища , если запущена среда разработки.

Первые два шага необходимы, в то время как шаги 3 и 4 я настоятельно рекомендую, но они не являются обязательными.

Теперь мы наконец закончили … и можем использовать хранилище в наших компонентах!

Http service factory

Services which extend build-in classes are required to have service provider defined and the factory. I am storing my factories into _factories directory. From CoreModule decorator you could see how am I defining service provider.

And this is the factory:

import { XHRBackend } from '@angular/http';import { AngularReduxRequestOptions } from '../core/angular-redux-request.options';import { HttpService } from '../core/http.service';import { LoaderService } from '../core/loader/loader.service';function httpServiceFactory(backend: XHRBackend, options: AngularReduxRequestOptions, loaderService: LoaderService ) {    return new HttpService(backend, options, loaderService);}export { httpServiceFactory };

With this Http service is completed but we will see no loader cause it is not used in the App component.

Inside app.component.html I’ll insert angular-loader tag on the first line.

Closing

Now we have functional loader on every get request, if you are curious to see how it’ll look checkout Live Demo. Try clicking Load New button few times to see it in action.

Development history

AngularJS was originally developed in 2009 by Miško Hevery at Brat Tech LLC as the software behind an online JSON storage service, that would have been priced by the megabyte, for easy-to-make applications for the enterprise. This venture was located at the web domain «GetAngular.com», and had a few subscribers, before the two decided to abandon the business idea and release Angular as an open-source library.

The 1.6 release added many of the concepts of Angular to AngularJS, including the concept of a component-based application architecture. This release among others removed the Sandbox, which many developers believed provided additional security, despite numerous vulnerabilities that had been discovered that bypassed the sandbox. The current (as of June 2018) stable release of AngularJS is 1.7.0

In January 2018, a schedule was announced for phasing-out AngularJS: after releasing 1.7.0, the active development on AngularJS will continue till June 30, 2018. Afterwards, 1.7 will be supported till  June 30, 2021 as long-term support.

Legacy browser support

Versions 1.3 and later of AngularJS do not support Internet Explorer 8 or earlier. While AngularJS 1.2 supports IE8, its team does not.

Angular and AngularDart

Subsequent versions of AngularJS are simply called Angular. Angular is an incompatible TypeScript-based rewrite of AngularJS. Angular 4 was announced on 13 December 2016, skipping 3 to avoid a confusion due to the misalignment of the router package’s version which was already distributed as v3.3.0.

AngularDart works on Dart, which is an object-oriented, class defined, single inheritance programming language using C style syntax, that is different from Angular JS (which uses JavaScript) and Angular 2/ Angular 4 (which uses TypeScript). Angular 4 released in March 2017, with the framework’s version aligned with the version number of the router it used. Angular 5 was released on November 1, 2017. Key improvements in Angular 5 include support for progressive Web apps, a build optimizer and improvements related to Material Design. Angular 6 was released on 3rd May 2018, Angular 7 was released on 18th October 2018, and Angular 8 was released on May 28, 2019.
Angular follows Semantic Versioning standards, with each major version number indicating potentially breaking changes. Angular has pledged to provide 6 months of active support for each major version followed by 12 months of long term support. Major releases are bi-yearly with 1 to 3 minor releases for every major release.

Angular Universal

A normal Angular application executes in the browser, while Angular Universal generates static application pages on the server through server-side rendering (SSR).

Subject¶

В некоторых случаях целесообразнее использовать объекты типа . Тип — разновидность RxJS Observable, который может доставлять данные сразу нескольким подписчикам.

В примере выше для объекта типа регистрируются два подписчика. Далее для передачи значения и вызова функций-обработчиков подписчиков используется метод .

В результате в консоль будет выведено две строки:

RxJS Subject в свою очередь также имеет разновидности.

— передает новому подписчику последнее значение, в качестве аргумента принимает начальное значение.

— передает новому подписчику все предыдущие значения, принимаемый параметр — количество предыдущих значений.

— передает новому подписчику последнее значение, но только после того, как будет вызван метод .

Использование хранилища в некоторых компонентах

Может быть, сейчас вы думаете:

Да, я могу! Пожалуйста, не теряйте интерес, мы приближаемся к концу! Давайте посмотрим, как использовать наше хранилище …

Во-первых, давайте получим конфигурацию при запуске приложения:

Файл с описание компонента приложения

  1. Мы добавляем хранилище в наш .
  2. Мы передаём в значение из селектора , потому что мы хотим показать часть этой информации в HTML.
  3. В мы отправляем действие, чтобы получить и передать конфигурацию в хранилище.

Вот и всё … Мы уже написали код эффекта, который будет обрабатывать это действие, и редуктор, который будет обрабатывать успех этого эффекта. Как только хранилище приобретёт новое состояние, селектор изменит значение нашего свойства. Удивительно!

Вот как мы связываем данные конифгурации в HTML:

Файл с описанием HTML разметки компонента навигации приложения

Как только у изменится значение, мы увидим его в HTML.

Теперь давайте посмотрим список пользователей

Файл с описанием компонента пользователя

  1. Мы собираемся получить список пользователей также как и конфигурацию. Сначала мы внедряем хранилище в компонент пользователя.
  2. В мы отправляем действие, чтобы получить пользователей.
  3. Мы создаем свойство , и присваиваем ему список пользователей, используя селектор .

HTML выглядит так:

Файл с описанием HTML разметки компонента пользователя

Мы отображаем список пользователей в презентационном(тупом) компоненте, и привязываем выбранного пользователя к функции , которую мы видели в контейнерном(умном) компоненте пользователя ранее.

Отлично… а как мы показываем выбранного пользователя?…

Давайте посмотрим на компонент пользовательского контейнера:

Файл с описанием контейнерного компонента пользователя

Этот компонент получает параметр из (текущего url), а с остальным вы, вероятно, уже знакомы. Отправление в качестве параметра, выбор выбранного пользователя…

Если вы хотите увидеть весь код, просто зайдите в репозиторий GitHub.

Для отладки вы можете использовать инструменты разработчика, которые довольно просты в использовании… но данная статья и так уже достаточно подробная, и, я надеюсь, что вы без труда разберетесь с этими инструментами.

Когда использовать NGRX

Итак, по общему мнению, следует использовать в средних/крупных проектах, где управление состоянием становится трудным в обслуживании. Те кто фанатеют по шаблонам () скажут что-то вроде «если у вас есть состояние, у вас есть ».

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

При этом я считаю, что сильная команда разработчиков может решить использовать в проекте потому что они знают силу шаблона и операторов . И они чувствуют себя комфортно, работая и с тем, и с другим …

Ссылка на основную публикацию