Есть задача - вставить в template Angular-приложения внешний js-скрипт

Пример номер один

Самый простой, правильный и надежный способ - добавить скрипт в сборку приложения.

Пошагово:

  1. создать папку
    1
    
    scripts
    
    внутри директории
    1
    
    assets
    
    -
    1
    
    src/assets/scripts
    
  2. поместить js-скрипт внутрь созданной папки -
    1
    
    src/assets/scripts/awesome.js
    
  3. открыть файл
    1
    
    angular.json
    
    в корне проекта
  4. добавить путь к скрипту в ключе
    1
    
    scripts
    
    :
{
  "projects": {
    "awesome-project": {
      "architect": 
            "scripts": ["src/assets/scripts/awesome.js,]
          },
          ....
}

Пример номер два

Есть еще способ добавления - при помощи

1
Renderer2
:

constructor(
  @Inject(DOCUMENT) private document: Document,
  private renderer2: Renderer2
) {}

ngOnInit(): void {
  const textScript = this.renderer2.createElement('script');
  textScript.src = 'https://code.jquery.com/jquery-3.3.1.slim.min.js';
  this.renderer2.appendChild(this.document.body, textScript);

  const srcScript = this.renderer2.createElement('script');
  srcScript.type = 'text/javascript';
  srcScript.text = `
    (function() {
      console.log('Hello from Siberia!')
    }());
  `;
  this.renderer2.appendChild(this.document.body, srcScript);
}

Пробовал этот способ - работает; но в консоли браузера появляется ошибка о необъявленной переменной X; отказался от этого способа.

Итог

Мне с первого раза помог способ номер один.

Что такое readonly в TypeScript

Если кратко - есть

1
const
- для создания констант в приложении. Объявили константу и один раз присвоили ей значение - все, больше изменить значение константы не получится - на то она и константа:

const abc: string = 'apple';
abc = 'melon';

… строка

1
abc = 'melon'
- будет с ошибкой - “Cannot assign to ‘abc’ because it is a constant”.

1
readonly
- это аналог
1
const
, только - для полей объекта; объявили объект, указали у него свойство с
1
readonly
; один раз - присвоили этому полю значение - все, переприсвоить его уже не получится:

interface Person {
  readonly name: string,
  age: number
}

const person: Person = {
  name: 'John',
  age: 20
};

person.age = 21;
person.name = 'Mary';

… последняя строка -

1
person.name = 'Mary'
- в ней TypeScript выдаст ошибку - “Cannot assign to ‘name’ because it is a read-only property”.

Поле объекта с квалификатором

1
readonly
- неизменяемое свойство объекта.

Для меня немного запутанная картина с именованными областями отображения и главное - с правильной настройкой. Нужно немного прояснить для себя.

Первое - настройка маршрутов. В ключе outlet указываем имя дополнительной области outlet - aux:

const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', component: FirstComponent },
  { path: 'chat', component: ChatComponent, outlet: 'aux' },
];

В шаблоне обозначаем разметку для дополнительной области отображения и указываем ее имя через атрибут name - какое указали и в маршрутах:

<div style="display: flex">
  <router-outlet></router-outlet>
  <router-outlet name="aux"></router-outlet>
</div>

В навигации в директиве routerLink - добавляем конфигурационный объект с ключом outlets. Значение этого ключа - объект с ключами primary и aux; эти ключи - имена областей отрисовки outlets;

имя primary - это имя по умолчанию; имя aux - это то имя дополнительной области отображения, которое указали в маршруте.

Самое неочевидное - это значения этих ключей. Значения - это path, указанный в настройках маршрута - path: ‘home’, path: ‘chat’.

<nav>
  <a [routerLink]="['/']">first</a>
  <a [routerLink]="['/second']">second</a>
  <a [routerLink]="[{ outlets: { primary: 'home', aux: 'chat' } }]">open chat</a>
  <a [routerLink]="[{ outlets: { aux: null } }]">close chat</a>
</nav>

В Angular есть встроенный инструмент, который позволяет проверить, насколько покрыты тестами различные части проекта.

Запуск для генерации отчета покрытия тестами - команда:

ng test --watch=false --code-coverage

После выполнения команды в корне проекта будет создана директория coverage - внутри нужно найти файл index.html, который нужно открыть в браузере. Отобразится страница с графиками покрытия различных частей тестами.

В конфигурационном файле karma.conf можно настроить минимумы, допустимые в проекте для покрытия тестами его функциональных частей.

Для этого в файле нужно найти поле coverageIstanbulReporter и дописать в нем ключ thresholds со значениями:

coverageIstanbulReporter: {
  reports: [ 'html', 'lcovonly' ],
  fixWebpackSourcePaths: true,
  thresholds: {
    statements: 70,
    lines: 70,
    branches: 70,
    functions: 70
  }
}

… где 70 - это 70 процентов (%) - пороговое значение threshold для каждой из частей проекта.


По умолчанию при scaffolding нового Angular-проекта в настройках используется пробелы spaces для задания отступов indent. Но иногда требования компании\команды бывают такими, что нужно использовать tabs вместо spaces.

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

Файл tslint.json:

...
"indent": [true, "tabs", 2]
...

Файл .prettierrc - если используется Prettier в проекте:

...
"useTabs": true
...

Файл .editorconfig:

[*]
indent_style = tabs
...