Skip to content

Commit

Permalink
Merge pull request #609 from stillst/feat-ru-challenges
Browse files Browse the repository at this point in the history
docs(ru): add translations
  • Loading branch information
tomalaforge authored Feb 21, 2024
2 parents 6817512 + 595c6f3 commit 2551d6d
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 9 deletions.
43 changes: 43 additions & 0 deletions docs/src/content/docs/ru/challenges/angular/1-projection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: 🟢 Проекция контента
description: Challenge 1 заключается в изучении проекции элементов DOM через компоненты
author: thomas-laforge
challengeNumber: 1
command: angular-projection
blogLink: https://medium.com/@thomas.laforge/create-a-highly-customizable-component-cc3a9805e4c5
videoLink:
link: https://www.youtube.com/watch?v=npyEyUZxoIw&ab_channel=ArthurLannelucq
alt: Projection video by Arthur Lannelucq
flag: FR
sidebar:
order: 1
---

## Информация

Проекция контента в Angular - это мощная техника для создания компонентов с гибко настраиваемым внешним видом. Понимание и использование концепций <b>ng-content</b> и <b>ngTemplateOutlet</b> может значительно вам помочь создавать компоненты, предназначенные для повторного использования.

[Здесь](https://angular.io/guide/content-projection#projecting-content-in-more-complex-environments) вы можете изучить все о <b>ng-content</b>, начиная с простых примеров и до более сложных.

Документацию <b>ngTemplateOutlet</b>t, вместе с базовыми примерами, можно найти [тут](https://angular.io/api/common/NgTemplateOutlet).

Имея эти два инструмента в своем распоряжении, вы теперь готовы пройти испытание.

## Пояснение

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

Хотя приложение работает, его внутреннее устройство далеко от идеала. Каждый раз, когда вам нужно реализовать новую карточку, вам придется изменять `card.component.ts`. В реальных проектах этот компонент может использоваться во многих приложениях. Цель этого упражнения создать `CardComponent`, внешний вид которого можно настроить без каких-либо изменений. После того как вы создадите этот компонент, вы можете создать `CityCardComponent` без модификации `CardComponent`.

## Ограничения

- Вы <b>должны</b> провести рефакторинг `CardComponent` и `ListItemComponent`.
- Директива `NgFor` должна быть определена и должна оставаться внутри `CardComponent`, несмотря на возможное желание перенести её в `ParentCardComponent`,как это сделано в `TeacherCardComponent`.
- `CardComponent` не должен содержать `NgIf` или `NgSwitch`.
- CSS: избегайте использования `::ng-deep`. Ищите альтернативные способы стилизации с помощью CSS.

## Дополнительные задачи

- Попробуйте использовать новый синтаксис для циклов и условий (документация [тут](https://angular.dev/guide/templates/control-flow)).
- Используйте signal API для управления состоянием компонентов (документация [тут](https://angular.dev/guide/signals)).
- Для ссылки на шаблон используйте директивы вместо магических строк ([What is wrong with magic strings?](https://softwareengineering.stackexchange.com/a/365344)).
18 changes: 18 additions & 0 deletions docs/src/content/docs/ru/challenges/angular/21-achor-scrolling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: 🟢Навигация по якорю
description: Испытание 21 про навигацию на странице с помощью якоря
author: thomas-laforge
challengeNumber: 21
command: angular-anchor-scrolling
sidebar:
order: 4
---

## Информация

Вы начинаете с приложения, которое имеет базовую навигацию и навигацию с использованием якорей в `HomeComponent`. Однако, использование `href` каждый раз создает новый путь и обновляет страницу.

## Пояснение

- Ваша задача - рефакторинг этого приложения для использования встроенного инструмента навигации, для более эффективной работы в рамках фреймворка Angular. Вы можете использовать router, но лучше остаться в шаблоне и использовать `RouterLink` директиву.
- Для улучшения пользовательского опыта, добавьте плавную прокрутку.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
title: 🔴 Типизация ContextOutlet
description: Испытание 4 про строгую типизацию ngContextOutlet директивы
author: thomas-laforge
challengeNumber: 4
command: angular-context-outlet-type
blogLink: https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6
sidebar:
order: 201
---

## Информация

В Angular есть статическая функция [`ngTemplateContextGuard`](https://angular.io/guide/structural-directives#typing-the-directives-context) для строгой типизации структурных директив.

Однако, контекстом **NgTemplateOutlet** является **Object**. Но с помощью вышеупомянутой гарда, мы можем улучшить это поведение.

## Пояснение

В этом испытании, мы хотим научиться строго типизировать ng-template в AppComponent.

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

### Уровень 1: Известный интерфейс

Сейчас код выглядит следующим образом.

![Unkown Person](../../../../../assets/4/unknown-person.png 'Unkown Person')

Как мы видим, у переменной name тип "any". Мы хотим вывести правильный тип.

### Уровень 2: Обобщённый интерфейс

Сейчас код выглядит следующим образом.

![Unkown Student](../../../../../assets/4/unknown-student.png 'Unkown Student')

Как мы видим, у переменной student тип "any". Мы хотим вывести правильный тип.

Но на этот раз, мы хотим передавать в `ListComponent` список из любых объектов. И мы все равно хотим, чтобы был выведен правильный тип.
36 changes: 36 additions & 0 deletions docs/src/content/docs/ru/challenges/angular/8-pipe-pure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
title: 🟢Чистый пайп
description: Испытание 8 про создание чистого пайпа
author: thomas-laforge
challengeNumber: 8
command: angular-pipe-easy
blogLink: https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d
sidebar:
order: 3
---

## Информация

This is the first of three `@Pipe()` challenges, the goal of this series is to master **pipes** in Angular.
Это первое испытание про `@Pipe()` из трех, цель этой серии испытаний - освоить работу с **pipes** в Angular.

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

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

По умолчанию пайпы чистые, но вы должны знать, что установка `pure` в false может привести к неэффективности, поскольку это увеличивает количество перерисовок.

:::note[Примечание]
**Чистые** пайп вызывается только когда изменяется входное значение.\
**Нечистый** пайп вызывается на каждый цикл обнаружения изменений.
:::

Существуют несколько полезных предопределенных пайпов, таких как DatePipe, UpperCasePipe и CurrencyPipe. Чтобы узнать больше о пайпах в Angular, ознакомьтесь с документацией API [здесь](https://angular.io/guide/pipes).

## Пояснение

В этом упражнении необходимо превратить вызов функции в шаблоне в использование пайпа.

## Ограничение

- Пайп должен быть типизирован.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
title: 🟠 Control Value Accessor
description: Испытание 41 про создание пользовательское поле формы которое использует интерфейс ControlValueAccessor.
author: stanislav-gavrilov
challengeNumber: 41
command: forms-control-value-accessor
sidebar:
order: 1
---

## Информация

Цель этого испытания создать пользовательское поле формы, которое использует API формы Angular через `ControlValueAccessor`. Документацию можно посмотреть [здесь](https://angular.io/api/forms/ControlValueAccessor). Этот интерфейс критически важен для создания пользовательских элементов управления формами, которые могут беспрепятственно взаимодействовать с API форм Angular.

## Пояснение

Задача - использовать контрол в `feedbackForm` напрямую, чтобы убрать необходимость в использовании `@Output` для получения значения из `app-rating-control` и установки его в `FormGroup`.
Кроме того, вы должны добавить валидацию для нового элемента управления, чтобы гарантировать наличие данных о рейтинге. (Кнопка отправки формы должна быть отключена, если форма недействительна).

Сейчас компонент рейтинга используется следующим образом:

```html
<app-rating-control (ratingUpdated)="rating = $event"></app-rating-control>
```

```ts
rating: string | null = null;

onFormSubmit(): void {
this.feedBackSubmit.emit({
...this.feedbackForm.value,
rating: this.rating, // not inside the FormGroup and no validation
});
}
```

Необходимо, чтобы компонент можно было использовать так:

```html
<app-rating-control [formControl]="feedbackForm.controls.rating"></app-rating-control>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: 🟠 Веб-воркеры
description: Испытание 40 о том как создать и использовать веб-воркер
author: thomas-laforge
challengeNumber: 40
command: performance-christmas-web-worker
sidebar:
order: 119
---

## Информация

Это испытание было создано для [Angular Advent Calendar](https://angularchristmascalendar.com) 2023.

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

> Пояснение: Для того, чтобы вызвать зависание приложения, загрузчик использует функцию, выполняющую очень сложные вычисления. Хотя возможно было бы использовать обычный таймер, но это не суть данного испытания.
Так как JavaScript работает в однопоточном режиме, выполнение ресурсоемких задач препятствует обновлению пользовательского интерфейса браузера и реагированию на клики мыши или другие действия. Задача этого испытания - разгрузить основной поток, перенеся сложные вычисления в отдельный поток. Для этой цели мы будем использовать веб-воркеры. Веб-воркеры способны запускать скрипты в фоне, не влияя на основной поток, что позволяет браузеру сохранять высокое качество пользовательского взаимодействия.

В Angular использование этой технологии не так распространено, но внедрить её довольно легко. Есть схематик, который вы можете найти [здесь](https://angular.io/guide/web-worker) чтобы начать.

## Пояснение

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

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

:::note[Пояснение]
Поскольку мы находимся в рабочем пространстве Nx, просто замените команду `ng` на `nx` при запуске схематика.

Если `nx` не установлен глобально на вашем компьютере, добавьте префикс `npx` к вашей команде.
:::
18 changes: 9 additions & 9 deletions docs/src/content/i18n/ru.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"page.title.challenge": "Испытание",
"author.createdBy": "Создано",
"buttons.email": "Email subscription",
"buttons.star": "Дать звезду",
"buttons.sponsor": "Спонсор",
"buttons.clipboardCopy": "Copied!",
"buttons.email": "Подписаться на email рассылку",
"buttons.star": "Добавить звезду",
"buttons.sponsor": "Спонсировать",
"buttons.clipboardCopy": "Скопировано!",
"404.text": "Страница не найдена. Проверьте URL-адрес или воспользуйтесь строкой поиска.",
"challenge.footer.note": "Примечание",
"challenge.footer.running": "Запустите проект, выполнив команду:",
Expand All @@ -13,12 +13,12 @@
"challenge.footer.communityAnswers": "Решения сообщества",
"challenge.footer.authorAnswer": "Решение автора",
"challenge.footer.blogPost": "Статья",
"challenge.footer.video": "Video",
"challenge.footer.video": "Видео",
"challenge.footer.gettingStarted.title": "Чтобы пройти это испытание, прочитайте:",
"challenge.footer.gettingStarted.link": "Первые шаги",
"challenge.footer.upvoteAnswer": "You can upvote an answer with a 👍 if you like it",
"subscription.button": "Subscribe",
"challenge.footer.upvoteAnswer": "Вы можете проголосовать за ответ 👍 если он вам понравился",
"subscription.button": "Подписаться",
"subscription.email": "username@gmail.com",
"subscription.note.title": "Notes",
"subscription.note.description": "This email will only be used for sending new challenges updates"
"subscription.note.title": "Примечание",
"subscription.note.description": "Этот email будет использоваться только для сообщений о новых испытаниях"
}

0 comments on commit 2551d6d

Please sign in to comment.