mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-11 05:13:02 -05:00
docs: add ru translations
This commit is contained in:
43
docs/src/content/docs/ru/challenges/angular/1-projection.md
Normal file
43
docs/src/content/docs/ru/challenges/angular/1-projection.md
Normal 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)).
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: 🟢Навигация по якорю
|
||||
description: Испытание 21 про навигацию на странице с помощью якоря
|
||||
author: thomas-laforge
|
||||
challengeNumber: 21
|
||||
command: angular-anchor-scrolling
|
||||
sidebar:
|
||||
order: 4
|
||||
---
|
||||
|
||||
## Информация
|
||||
|
||||
Вы начинаете с приложения, которое имеет базовую навигацию и навигацию с использованием якорей в `HomeComponent`. Однако, использование `href` каждый раз создает новый путь и обновляет страницу.
|
||||
|
||||
## Пояснение
|
||||
|
||||
- Ваша задача - рефакторинг этого приложения для использования встроенного инструмента навигации, для более эффективной работы в рамках фреймворка Angular. Вы можете использовать router, но лучше остаться в шаблоне и использовать `RouterLink` директиву.
|
||||
- Для улучшения пользовательского опыта, добавьте плавную прокрутку.
|
||||
@@ -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: Известный интерфейс
|
||||
|
||||
Сейчас код выглядит следующим образом.
|
||||
|
||||

|
||||
|
||||
Как мы видим, у переменной name тип "any". Мы хотим вывести правильный тип.
|
||||
|
||||
### Уровень 2: Обобщённый интерфейс
|
||||
|
||||
Сейчас код выглядит следующим образом.
|
||||
|
||||

|
||||
|
||||
Как мы видим, у переменной student тип "any". Мы хотим вывести правильный тип.
|
||||
|
||||
Но на этот раз, мы хотим передавать в `ListComponent` список из любых объектов. И мы все равно хотим, чтобы был выведен правильный тип.
|
||||
36
docs/src/content/docs/ru/challenges/angular/8-pipe-pure.md
Normal file
36
docs/src/content/docs/ru/challenges/angular/8-pipe-pure.md
Normal 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).
|
||||
|
||||
## Пояснение
|
||||
|
||||
В этом упражнении необходимо превратить вызов функции в шаблоне в использование пайпа.
|
||||
|
||||
## Ограничение
|
||||
|
||||
- Пайп должен быть типизирован.
|
||||
@@ -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>
|
||||
```
|
||||
@@ -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 будет использоваться только для о новых испытаниях"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user