Merge pull request #609 from stillst/feat-ru-challenges

docs(ru): add translations
This commit is contained in:
Laforge Thomas
2024-02-21 08:55:24 +01:00
committed by GitHub
7 changed files with 220 additions and 9 deletions

View File

@@ -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)).

View File

@@ -0,0 +1,18 @@
---
title: 🟢Навигация по якорю
description: Испытание 21 про навигацию на странице с помощью якоря
author: thomas-laforge
challengeNumber: 21
command: angular-anchor-scrolling
sidebar:
order: 4
---
## Информация
Вы начинаете с приложения, которое имеет базовую навигацию и навигацию с использованием якорей в `HomeComponent`. Однако, использование `href` каждый раз создает новый путь и обновляет страницу.
## Пояснение
- Ваша задача - рефакторинг этого приложения для использования встроенного инструмента навигации, для более эффективной работы в рамках фреймворка Angular. Вы можете использовать router, но лучше остаться в шаблоне и использовать `RouterLink` директиву.
- Для улучшения пользовательского опыта, добавьте плавную прокрутку.

View File

@@ -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` список из любых объектов. И мы все равно хотим, чтобы был выведен правильный тип.

View File

@@ -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).
## Пояснение
В этом упражнении необходимо превратить вызов функции в шаблоне в использование пайпа.
## Ограничение
- Пайп должен быть типизирован.

View File

@@ -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>
```

View File

@@ -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` к вашей команде.
:::

View File

@@ -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": "Запустите проект, выполнив команду:",
@@ -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 будет использоваться только для сообщений о новых испытаниях"
}