freeCodeCamp/guide/russian/angular/views/index.md

243 lines
26 KiB
Markdown
Raw Normal View History

2018-10-12 20:00:59 +00:00
---
title: Views
localeTitle: Просмотры
---
# Просмотры
#### мотивация
Представления предлагают необходимый уровень абстракции. Они сохраняют Угловую независимость от конкретных утилит платформы. В качестве кросс-платформенной технологии Angular использует свои возможности для подключения к платформе.
Для каждого элемента HTML шаблона Angular существует соответствующее представление. Angular рекомендует взаимодействовать с платформами через эти представления. Хотя прямые манипуляции все еще возможны, Angular предупреждает об этом. Angular предлагает собственный интерфейс прикладного программирования (API) для замены собственных манипуляций.
Отказ от просмотра API-интерфейса для платформы имеет свои последствия. При разработке Angular в веб-браузере элементы существуют в двух местах: DOM и представлении. Мессинг только с DOM не влияет на представление.
Поскольку Angular не взаимодействует с платформой, это создает разрыв. Представления должны зеркально отображать платформу один к одному. В противном случае Угловые ресурсы отходов управляют элементами, которые не соответствуют им. Это ужасно в случае удаленных элементов.
Подобные расхождения делают взгляды ненужными. Никогда не забывайте, что Angular является универсальной платформой развития, прежде всего. Представления являются необходимой абстракцией для этой цели.
Соблюдая взгляды, угловые приложения будут работать на всех поддерживаемых платформах разработки. Платформы включают в себя Web, Android и Apple iOS.
#### Заметка
Отсюда, эта статья предполагает среду веб-браузера. Не стесняйтесь мысленно заменить DOM чем-то более применимым к вашей предпочитаемой платформе.
#### Что такое Views?
Представления почти как их собственный виртуальный DOM. Каждое представление содержит ссылку на соответствующий раздел DOM. Внутри представления находятся узлы, которые отражают то, что находится в этом разделе. Угловой присваивает один узел вида на элемент DOM. Каждый узел содержит ссылку на соответствующий элемент.
Когда Angular проверяет изменения, он проверяет представления. Угловое избегает DOM под капотом. Мнения ссылаются на DOM от его имени. Существуют и другие механизмы для обеспечения того, чтобы изменения вида отображались в DOM. И наоборот, изменения в DOM не влияют на представления.
Опять же, взгляды распространены на всех платформах разработки, кроме DOM. Даже если они разрабатываются для одной платформы, мнения по-прежнему считаются лучшей практикой. Они гарантируют, что Угловая имеет правильную интерпретацию DOM.
Представления могут отсутствовать в сторонних библиотеках. Прямая манипуляция с DOM - это экранирующий люк для такого сценария. Конечно, не ожидайте, что приложение будет работать с кросс-платформенными.
#### Типы просмотров
Существует два основных типа представлений: встроенный и хост.
Также существуют контейнеры представлений. Они содержат встроенные и хост-представления и часто называются простыми «представлениями».
Каждый класс `@Component` регистрирует контейнер вида (просмотр) с помощью Angular. Новые компоненты генерируют настраиваемый селектор, предназначенный для определенного элемента DOM. Представление прикрепляется к этому элементу везде, где оно появляется. Угловой теперь знает, что компонент существует, глядя на модель представления.
Представления хоста прикрепляются к компонентам, созданным динамически с заводами. Фабрики представляют собой основу для создания экземпляра представления. Таким образом, приложение может создавать экземпляр хоста компонента во время выполнения. Хост-представление прикрепляется к обертке компонента за его экземпляр. В этом представлении хранятся данные, описывающие возможности обычных компонентов.
`<ng-template></ng-template>` является сродни элементу HTML5 `<template></template>` . `ng-template` Angular работает со встроенными представлениями. Эти представления не привязаны к элементам DOM в отличие от представлений хоста. Они идентичны представлениям хоста, поскольку они оба типа существуют внутри контейнеров просмотра.
Имейте в виду, что `ng-template` не является элементом DOM. Он закомментирован позже, оставив только узлы встроенного представления.
Разница зависит от входных данных; встроенные представления не хранят данные компонента. Они хранят ряд элементов в качестве узлов, содержащих его шаблон. Шаблон составляет все innerHTML `ng-template` . Каждый элемент внутри встроенного представления представляет собой отдельный отдельный узел представления.
#### Представления и контейнеры для хостов
В представлениях _хоста размещаются_ динамические компоненты. Просмотреть контейнеры (виды) автоматически присоединяются к элементам, уже находящимся в шаблоне. Представления могут присоединяться к любому элементу за пределами того, что уникально для классов компонентов.
Подумайте о традиционном способе создания компонентов. Он начинается с создания класса, декорирования его с помощью `@Component` и заполнения метаданных. Этот подход применяется для любого заранее определенного элемента компонента шаблона.
Попробуйте использовать команду интерфейса командной строки (CLI): `ng generate component [name-of-component]` . Это дает следующее.
```typescript
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit {
constructor() { }
ngOnInit() { }
}
```
Это создает компонент с `app-example` селектора. Это прикрепляет контейнер представления к `<app-example></app-example>` в шаблоне. Если бы это был корень приложения, его представление инкапсулировало бы все другие представления. Корневой вид обозначает начало приложения с точки зрения Углового.
Динамическое создание компонентов и их регистрация в модели с угловым видом занимает несколько дополнительных шагов. Структурные директивы помогают управлять динамическим контентом ( `*ngIf, *ngFor, and *ngSwitch…` ). Однако директивы не масштабируются для больших приложений. Слишком много структурных директив усложняет шаблон.
Именно здесь пригодится создание экземпляров из существующей логики классов. Этим компонентам необходимо создать представление хоста, которое может вставляться в модель представления. Представления хоста содержат данные для компонентов, так что Angular распознает их структурную цель.
##### Хост-просмотр продолжается
Каждый компонент имеет определение класса. Однако JavaScript не поддерживает классы. Классы - это синтаксический сахар. Вместо этого они производят функции, содержащие компоненты.
Фабрики действуют как чертежи для представлений хостов. Они создают представления для взаимодействия с Angular от имени своих компонентов. Представления хоста прикрепляются к элементам DOM. Технически любой элемент в порядке, но наиболее распространенной целью является `<ng-component></ng-component>` .
Вначале должен существовать контейнер представления (представление) для размещения представлений. `<ng-container></ng-container>` - отличное место для прикрепления контейнера вида. Контейнеры просмотра - это те же типы представлений, которые также применяются к элементам класса шаблона.
Несколько помощников и ссылки из `@angular/core` предоставляют другие необходимые утилиты. Следующий пример объединяет все это.
```typescript
// another.component.ts
import { Component } from '@angular/core';
@Component({
template: `
<h1>Another Component Content</h1>
<h3>Dynamically Generated!</h3>
`
})
export class AnotherComponent { }
```
```typescript
// example.component.ts
import { AfterViewInit, Component, ViewChild,
ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
import { AnotherComponent } from './another.component';
@Component({
selector: 'app-example',
template: `
<h1>Application Content</h1>
<ng-container #container></ng-container>
<h3>End of Application</h3>
`,
entryComponents: [ AnotherComponent ]
})
export class ExampleComponent implements AfterViewInit {
@ViewChild("container", { read: ViewContainerRef }) ctr: ViewContainerRef;
constructor(private resolve: ComponentFactoryResolver) { }
ngAfterViewInit() {
const factory = this.resolve.resolveComponentFactory(AnotherComponent);
this.ctr.createComponent(factory);
}
}
```
Предположим, что AnotherComponent и ExampleComponent объявлены в том же модуле. AnotherComponent - это простой компонент класса, динамически добавленный в представление ExampleComponent. Метаданные entryComponents для `entryComponents` должны содержать AnotherComponent для [начальной загрузки](https://angular.io/guide/bootstrapping) .
Хотя ExampleComponent является частью шаблона, AnotherComponent остается отсоединенным. Он динамически отображает шаблон из ExampleComponent.
Есть два контейнера представления: `<app-example></app-example>` и `<ng-container></ng-container>` . Представление хоста для этого примера будет вставляться в `ng-container` .
`AfterViewInit` жизненного цикла `AfterViewInit` запускается после `@ViewChild` запросов `@ViewChild` . Используя _ссылочную переменную шаблона_ `#container` , `@ViewChild` ссылается на `ng-container` как `ctr` .
`ViewContainerRef` - тип ссылки для контейнеров представлений (просмотров). `ViewContainerRef` ссылается на представление, которое поддерживает вставку других представлений. `ViewContainerRef` содержит больше методов управления содержащимися представлениями.
Благодаря внедрению зависимостей конструктор создает экземпляр службы `ComponentFactoryResolver` для Angular. Эта служба извлекает заводскую функцию (схема представления хоста) AnotherComponent.
Единственный аргумент `createComponent` требует фабрики. Функция `createComponent` происходит из `ViewContainerRef` . Он создает экземпляр AnotherComponent под представлением хоста, производным от фабрики компонента.
Затем представление узла вставляется в контейнер представления. `<ng-component></ng-component>` обертывает компонент внутри контейнера представления. Он придает ему вышеупомянутый вид на хост. `ng-component` - соединение узла с DOM.
Существуют и другие способы создания динамического представления хоста из компонента. Другие способы часто [фокусируются на оптимизации](https://blog.angularindepth.com/working-with-dom-in-angular-unexpected-consequences-and-optimization-techniques-682ac09f6866) .
`ViewContainerRef` содержит мощный API. Он может управлять любым количеством представлений хостом или встроенным в его представление. API включает операции просмотра, такие как вставка, перемещение и удаление. Это позволяет вам манипулировать моделью DOM через модель Angular. Это лучшая практика, так что Angular и DOM соответствуют друг другу.
#### Встроенные представления
Примечание: встроенные представления присоединяются к другим представлениям без добавления ввода. Представления хоста присоединяются к элементу DOM с входными данными из представления своего хоста, описывая его как компонент.
Структурные директивы создают [`ng-template` окружающий кусок содержимого HTML](https://angular.io/guide/structural-directives#the-asterisk--prefix) . Элемент-хозяин директивы имеет прикрепленный контейнер вида. Это делает его таким, чтобы контент мог условно отобразить его предполагаемый макет.
В `ng-template` содержатся встроенные узлы представления, представляющие каждый элемент внутри его внутреннего HTTML. `ng-template` ни в коем случае не является элементом DOM. Он сам замечает. Теги определяют длину встроенного представления.
#### Встроенные представления продолжаются
Создание экземпляра встроенного представления не требует внешних ресурсов за пределами его собственных ссылок. Запрос `@ViewChild` может получить это.
С ссылкой на шаблон, вызов `createEmbeddedView` из него делает трюк. ВнутреннийHTML ссылки становится его собственным встроенным представлением представления.
В следующем примере `<ng-container></ng-container>` - контейнер представления. `ng-container` комментируется во время компиляции точно так же, как `ng-template` . Таким образом, он обеспечивает выход для вставки встроенного представления, сохраняя при этом DOM lean.
Встроенный шаблон просмотра вставляется в расположение расположения `ng-container` . Этот вновь вставленный вид не имеет дополнительной инкапсуляции вида, кроме контейнера представления. Помните, как это отличается от представлений хоста (представления хоста прикрепляются к их `ng-component` элемента `ng-component` ).
```typescript
import { Component, AfterViewInit, ViewChild,
ViewContainerRef, TemplateRef } from '@angular/core';
@Component({
selector: 'app-example',
template: `
<h1>Application Content</h1>
<ng-container #container></ng-container> <!-- embed view here -->
<h3>End of Application</h3>
<ng-template #template>
<h1>Template Content</h1>
<h3>Dynamically Generated!</h3>
</ng-template>
`
})
export class ExampleComponent implements AfterViewInit {
@ViewChild("template", { read: TemplateRef }) tpl: TemplateRef<any>;
@ViewChild("container", { read: ViewContainerRef }) ctr: ViewContainerRef;
constructor() { }
ngAfterViewInit() {
const view = this.tpl.createEmbeddedView(null);
this.ctr.insert(view);
}
}
```
`@ViewChild` для _ссылочной переменной шаблона_ `#template` . Это предоставляет ссылку на `TemplateRef` типа `TemplateRef` . `TemplateRef` содержит функцию `createEmbeddedView` . Он создает шаблон в виде встроенного представления.
Единственный аргумент `createEmbeddedView` предназначен для контекста. Если вы хотите передать дополнительные метаданные, вы можете сделать это здесь как объект. Поля должны совпадать с атрибутами `ng-template` ( `let-[context-field-key-name]=“value”` ). Передача `null` не требует дополнительных метаданных.
Второй запрос `@ViewChild` предоставляет ссылку на `ng-container` как `ViewContainerRef` . Встроенные представления присоединяются только к другим представлениям, а не к DOM. `ViewContainerRef` ссылается на представление, которое занимает встроенный просмотр.
Встроенный вид также может вставляться в представление компонента в `<app-example></app-example>` . Этот подход позиционирует представление в самом конце представления ExampleComponent. Однако в этом примере мы хотим, чтобы содержимое отображалось в самой середине, где находится `ng-container` .
Функция `insert` `ViewContainerRef` ставляет_ встроенный вид в `ng-container` . Содержимое представления отображается в предполагаемом месте прямо в середине представления ExampleComponent.
#### Вывод
Манипулирование DOM с помощью специальных методов платформы не рекомендуется. Создание и управление узким набором представлений держит Angular и DOM на одной странице. Обновление представлений сообщает Угловое состояние текущего состояния DOM. Обновления представлений также переносятся на то, что отображается DOM.
Угловой обеспечивает гибкий интерфейс API для просмотра. Благодаря этому уровню абстракции возможно развитие независимых от платформы приложений. Конечно, сохраняется соблазн отказаться от стратегий, зависящих от платформы. Если у вас нет веских оснований, не пытайтесь придерживаться взглядов API Angular. Это даст прогнозируемые результаты на всех платформах.
Проверьте также ресурсы ниже! Эта статья просто царапает поверхность. В некоторых статьях есть много других случаев использования, слишком обширных для одной статьи.
## источники
* [AngularInDepth.com. «Просмотр компонентов, Просмотр хоста, Встроенный просмотр», # 40423772. 11 июля 2017. «В чем разница между представлением, представлением хоста и встроенным представлением»](https://stackoverflow.com/questions/40423772/what-is-the-difference-between-a-view-a-host-view-and-an-embedded-view)
* [Угловая команда. «Структурные директивы». _Google_ . Доступ к 31 мая 2018 года](https://angular.io/guide/structural-directives)
* [Корецкий, Максим. «Изучение методов манипуляции с угловым DOM с использованием ViewContainerRef». _Угловая глубина_ , 4 марта 2017. Доступ к 30 мая 2018 года.](https://blog.angularindepth.com/exploring-angular-dom-abstractions-80b3ebcfc02)
* [Корецкий, Максим. «Реализация расширенных сценариев манипуляции с DOM». _Youtube_ , загруженный ng-conf, 19 апреля 2018. Доступен 30 мая 2018 года](https://www.youtube.com/watch?v=vz9cNCkaPsY)
* [Корецкий, Максим. «Работа с DOM in Angular: неожиданные последствия и методы оптимизации». _Угловая глубина_ , 3 мая 2017 года. Доступ к 31 мая 2018 года](https://blog.angularindepth.com/working-with-dom-in-angular-unexpected-consequences-and-optimization-techniques-682ac09f6866)
## Ресурсы
* [Угловая документация](https://angular.io/guide/pipes)
* [Угловая глубина](https://blog.angularindepth.com)
* [ViewContainerRef](https://angular.io/api/core/ViewContainerRef)
* [TemplateRef](https://angular.io/api/core/TemplateRef)
* [Угловой репозиторий GitHub](https://github.com/angular/angular)
* [Угловая CLI](https://cli.angular.io)