Skip to content

Commit 2551d6d

Browse files
authored
Merge pull request #609 from stillst/feat-ru-challenges
docs(ru): add translations
2 parents 6817512 + 595c6f3 commit 2551d6d

7 files changed

Lines changed: 220 additions & 9 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
title: 🟢 Проекция контента
3+
description: Challenge 1 заключается в изучении проекции элементов DOM через компоненты
4+
author: thomas-laforge
5+
challengeNumber: 1
6+
command: angular-projection
7+
blogLink: https://medium.com/@thomas.laforge/create-a-highly-customizable-component-cc3a9805e4c5
8+
videoLink:
9+
link: https://www.youtube.com/watch?v=npyEyUZxoIw&ab_channel=ArthurLannelucq
10+
alt: Projection video by Arthur Lannelucq
11+
flag: FR
12+
sidebar:
13+
order: 1
14+
---
15+
16+
## Информация
17+
18+
Проекция контента в Angular - это мощная техника для создания компонентов с гибко настраиваемым внешним видом. Понимание и использование концепций <b>ng-content</b> и <b>ngTemplateOutlet</b> может значительно вам помочь создавать компоненты, предназначенные для повторного использования.
19+
20+
[Здесь](https://angular.io/guide/content-projection#projecting-content-in-more-complex-environments) вы можете изучить все о <b>ng-content</b>, начиная с простых примеров и до более сложных.
21+
22+
Документацию <b>ngTemplateOutlet</b>t, вместе с базовыми примерами, можно найти [тут](https://angular.io/api/common/NgTemplateOutlet).
23+
24+
Имея эти два инструмента в своем распоряжении, вы теперь готовы пройти испытание.
25+
26+
## Пояснение
27+
28+
Вы начнете с полностью работающего приложения, которое включает панель с карточкой учителя и карточкой студента. Цель состоит в том, чтобы реализовать карточку города.
29+
30+
Хотя приложение работает, его внутреннее устройство далеко от идеала. Каждый раз, когда вам нужно реализовать новую карточку, вам придется изменять `card.component.ts`. В реальных проектах этот компонент может использоваться во многих приложениях. Цель этого упражнения создать `CardComponent`, внешний вид которого можно настроить без каких-либо изменений. После того как вы создадите этот компонент, вы можете создать `CityCardComponent` без модификации `CardComponent`.
31+
32+
## Ограничения
33+
34+
- Вы <b>должны</b> провести рефакторинг `CardComponent` и `ListItemComponent`.
35+
- Директива `NgFor` должна быть определена и должна оставаться внутри `CardComponent`, несмотря на возможное желание перенести её в `ParentCardComponent`,как это сделано в `TeacherCardComponent`.
36+
- `CardComponent` не должен содержать `NgIf` или `NgSwitch`.
37+
- CSS: избегайте использования `::ng-deep`. Ищите альтернативные способы стилизации с помощью CSS.
38+
39+
## Дополнительные задачи
40+
41+
- Попробуйте использовать новый синтаксис для циклов и условий (документация [тут](https://angular.dev/guide/templates/control-flow)).
42+
- Используйте signal API для управления состоянием компонентов (документация [тут](https://angular.dev/guide/signals)).
43+
- Для ссылки на шаблон используйте директивы вместо магических строк ([What is wrong with magic strings?](https://softwareengineering.stackexchange.com/a/365344)).
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
title: 🟢Навигация по якорю
3+
description: Испытание 21 про навигацию на странице с помощью якоря
4+
author: thomas-laforge
5+
challengeNumber: 21
6+
command: angular-anchor-scrolling
7+
sidebar:
8+
order: 4
9+
---
10+
11+
## Информация
12+
13+
Вы начинаете с приложения, которое имеет базовую навигацию и навигацию с использованием якорей в `HomeComponent`. Однако, использование `href` каждый раз создает новый путь и обновляет страницу.
14+
15+
## Пояснение
16+
17+
- Ваша задача - рефакторинг этого приложения для использования встроенного инструмента навигации, для более эффективной работы в рамках фреймворка Angular. Вы можете использовать router, но лучше остаться в шаблоне и использовать `RouterLink` директиву.
18+
- Для улучшения пользовательского опыта, добавьте плавную прокрутку.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
title: 🔴 Типизация ContextOutlet
3+
description: Испытание 4 про строгую типизацию ngContextOutlet директивы
4+
author: thomas-laforge
5+
challengeNumber: 4
6+
command: angular-context-outlet-type
7+
blogLink: https://medium.com/@thomas.laforge/ngtemplateoutlet-type-checking-5d2dcb07a2c6
8+
sidebar:
9+
order: 201
10+
---
11+
12+
## Информация
13+
14+
В Angular есть статическая функция [`ngTemplateContextGuard`](https://angular.io/guide/structural-directives#typing-the-directives-context) для строгой типизации структурных директив.
15+
16+
Однако, контекстом **NgTemplateOutlet** является **Object**. Но с помощью вышеупомянутой гарда, мы можем улучшить это поведение.
17+
18+
## Пояснение
19+
20+
В этом испытании, мы хотим научиться строго типизировать ng-template в AppComponent.
21+
22+
Это упражнение имеет два уровня сложности:
23+
24+
### Уровень 1: Известный интерфейс
25+
26+
Сейчас код выглядит следующим образом.
27+
28+
![Unkown Person](../../../../../assets/4/unknown-person.png 'Unkown Person')
29+
30+
Как мы видим, у переменной name тип "any". Мы хотим вывести правильный тип.
31+
32+
### Уровень 2: Обобщённый интерфейс
33+
34+
Сейчас код выглядит следующим образом.
35+
36+
![Unkown Student](../../../../../assets/4/unknown-student.png 'Unkown Student')
37+
38+
Как мы видим, у переменной student тип "any". Мы хотим вывести правильный тип.
39+
40+
Но на этот раз, мы хотим передавать в `ListComponent` список из любых объектов. И мы все равно хотим, чтобы был выведен правильный тип.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
title: 🟢Чистый пайп
3+
description: Испытание 8 про создание чистого пайпа
4+
author: thomas-laforge
5+
challengeNumber: 8
6+
command: angular-pipe-easy
7+
blogLink: https://medium.com/ngconf/deep-dive-into-angular-pipes-c040588cd15d
8+
sidebar:
9+
order: 3
10+
---
11+
12+
## Информация
13+
14+
This is the first of three `@Pipe()` challenges, the goal of this series is to master **pipes** in Angular.
15+
Это первое испытание про `@Pipe()` из трех, цель этой серии испытаний - освоить работу с **pipes** в Angular.
16+
17+
Пайпы - удобный способ трансформации данных в вашем шаблоне. Разница между вызовом функции и пайпом заключается в том, что результат, возвращаемый чистыми пайпами, кэшируется. Таким образом, они не будут пересчитываться при каждом цикле обнаружения изменений, если их входные значения не изменились.
18+
19+
Pipes разработаны так, чтобы быть эффективными и оптимизированными для производительности. Они используют механизмы обнаружения изменений, чтобы пересчитывать значение только в случае изменения входных данных, минимизируя ненужные вычисления и улучшая производительность рендеринга.
20+
21+
По умолчанию пайпы чистые, но вы должны знать, что установка `pure` в false может привести к неэффективности, поскольку это увеличивает количество перерисовок.
22+
23+
:::note[Примечание]
24+
**Чистые** пайп вызывается только когда изменяется входное значение.\
25+
**Нечистый** пайп вызывается на каждый цикл обнаружения изменений.
26+
:::
27+
28+
Существуют несколько полезных предопределенных пайпов, таких как DatePipe, UpperCasePipe и CurrencyPipe. Чтобы узнать больше о пайпах в Angular, ознакомьтесь с документацией API [здесь](https://angular.io/guide/pipes).
29+
30+
## Пояснение
31+
32+
В этом упражнении необходимо превратить вызов функции в шаблоне в использование пайпа.
33+
34+
## Ограничение
35+
36+
- Пайп должен быть типизирован.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
title: 🟠 Control Value Accessor
3+
description: Испытание 41 про создание пользовательское поле формы которое использует интерфейс ControlValueAccessor.
4+
author: stanislav-gavrilov
5+
challengeNumber: 41
6+
command: forms-control-value-accessor
7+
sidebar:
8+
order: 1
9+
---
10+
11+
## Информация
12+
13+
Цель этого испытания создать пользовательское поле формы, которое использует API формы Angular через `ControlValueAccessor`. Документацию можно посмотреть [здесь](https://angular.io/api/forms/ControlValueAccessor). Этот интерфейс критически важен для создания пользовательских элементов управления формами, которые могут беспрепятственно взаимодействовать с API форм Angular.
14+
15+
## Пояснение
16+
17+
Задача - использовать контрол в `feedbackForm` напрямую, чтобы убрать необходимость в использовании `@Output` для получения значения из `app-rating-control` и установки его в `FormGroup`.
18+
Кроме того, вы должны добавить валидацию для нового элемента управления, чтобы гарантировать наличие данных о рейтинге. (Кнопка отправки формы должна быть отключена, если форма недействительна).
19+
20+
Сейчас компонент рейтинга используется следующим образом:
21+
22+
```html
23+
<app-rating-control (ratingUpdated)="rating = $event"></app-rating-control>
24+
```
25+
26+
```ts
27+
rating: string | null = null;
28+
29+
onFormSubmit(): void {
30+
this.feedBackSubmit.emit({
31+
...this.feedbackForm.value,
32+
rating: this.rating, // not inside the FormGroup and no validation
33+
});
34+
}
35+
```
36+
37+
Необходимо, чтобы компонент можно было использовать так:
38+
39+
```html
40+
<app-rating-control [formControl]="feedbackForm.controls.rating"></app-rating-control>
41+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: 🟠 Веб-воркеры
3+
description: Испытание 40 о том как создать и использовать веб-воркер
4+
author: thomas-laforge
5+
challengeNumber: 40
6+
command: performance-christmas-web-worker
7+
sidebar:
8+
order: 119
9+
---
10+
11+
## Информация
12+
13+
Это испытание было создано для [Angular Advent Calendar](https://angularchristmascalendar.com) 2023.
14+
15+
Это простое приложение, где нужно нажать на кнопку **Discover**, чтобы увидеть сюрприз, скрывающийся за черным экраном. Тем не менее, взаимодействие с приложением оставляет желать лучшего. При нажатии на кнопку происходит зависание страницы, а затем, после краткой задержки, секрет раскрывается мгновенно и без какой-либо плавности в анимации.
16+
17+
> Пояснение: Для того, чтобы вызвать зависание приложения, загрузчик использует функцию, выполняющую очень сложные вычисления. Хотя возможно было бы использовать обычный таймер, но это не суть данного испытания.
18+
19+
Так как JavaScript работает в однопоточном режиме, выполнение ресурсоемких задач препятствует обновлению пользовательского интерфейса браузера и реагированию на клики мыши или другие действия. Задача этого испытания - разгрузить основной поток, перенеся сложные вычисления в отдельный поток. Для этой цели мы будем использовать веб-воркеры. Веб-воркеры способны запускать скрипты в фоне, не влияя на основной поток, что позволяет браузеру сохранять высокое качество пользовательского взаимодействия.
20+
21+
В Angular использование этой технологии не так распространено, но внедрить её довольно легко. Есть схематик, который вы можете найти [здесь](https://angular.io/guide/web-worker) чтобы начать.
22+
23+
## Пояснение
24+
25+
Это испытание направлено на создание плавной анимации за счет перемещения функции, выполняющей сложные вычисления, в веб-воркер.
26+
27+
Для начала, используя схематик, создайте веб-воркер и перенесите в него функцию, вызывающую проблемы. После этих шагов анимация должна стать плавной, а отображение процента выполнения — обновляться, тем самым значительно улучшив пользовательский опыт.
28+
29+
:::note[Пояснение]
30+
Поскольку мы находимся в рабочем пространстве Nx, просто замените команду `ng` на `nx` при запуске схематика.
31+
32+
Если `nx` не установлен глобально на вашем компьютере, добавьте префикс `npx` к вашей команде.
33+
:::

docs/src/content/i18n/ru.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"page.title.challenge": "Испытание",
33
"author.createdBy": "Создано",
4-
"buttons.email": "Email subscription",
5-
"buttons.star": "Дать звезду",
6-
"buttons.sponsor": "Спонсор",
7-
"buttons.clipboardCopy": "Copied!",
4+
"buttons.email": "Подписаться на email рассылку",
5+
"buttons.star": "Добавить звезду",
6+
"buttons.sponsor": "Спонсировать",
7+
"buttons.clipboardCopy": "Скопировано!",
88
"404.text": "Страница не найдена. Проверьте URL-адрес или воспользуйтесь строкой поиска.",
99
"challenge.footer.note": "Примечание",
1010
"challenge.footer.running": "Запустите проект, выполнив команду:",
@@ -13,12 +13,12 @@
1313
"challenge.footer.communityAnswers": "Решения сообщества",
1414
"challenge.footer.authorAnswer": "Решение автора",
1515
"challenge.footer.blogPost": "Статья",
16-
"challenge.footer.video": "Video",
16+
"challenge.footer.video": "Видео",
1717
"challenge.footer.gettingStarted.title": "Чтобы пройти это испытание, прочитайте:",
1818
"challenge.footer.gettingStarted.link": "Первые шаги",
19-
"challenge.footer.upvoteAnswer": "You can upvote an answer with a 👍 if you like it",
20-
"subscription.button": "Subscribe",
19+
"challenge.footer.upvoteAnswer": "Вы можете проголосовать за ответ 👍 если он вам понравился",
20+
"subscription.button": "Подписаться",
2121
"subscription.email": "username@gmail.com",
22-
"subscription.note.title": "Notes",
23-
"subscription.note.description": "This email will only be used for sending new challenges updates"
22+
"subscription.note.title": "Примечание",
23+
"subscription.note.description": "Этот email будет использоваться только для сообщений о новых испытаниях"
2424
}

0 commit comments

Comments
 (0)