От автора: сегодня Angular Team выпустили бета-версию Angular 7. Многим из нас будет интересно узнать о функциях и исправлениях ошибок, которые мы можем увидеть в этой бета-версии.
Функции
Давайте сначала рассмотрим новые функции.
Angular Compatibility Compiler (ngcc)
Этот компилятор преобразует node_modules, скомпилированный с помощью ngc, в node_modules, который, выглядит, как скомпилированный с помощью ngtsc. Это преобразование позволит использовать такие «унаследованные» пакеты с помощью движка рендеринга Ivy.
DoBootstrap
Новый интерфейс привязки жизненного цикла ngDoBootstrap. Пример:
class AppModule implements DoBootstrap { ngDoBootstrap(appRef: ApplicationRef) { appRef.bootstrap(AppComponent); } }
Компилятор
Обновлены заполнители XMB (<ph>) с включением исходного значения поверх примера. Теперь заполнители могут по определению иметь один пример (<ex>) и текстовый узел. Текстовый узел используется TC как «оригинальное» значение из заполнителя, в то время как пример должен представлять фиктивное значение. Давайте рассмотрим это подробнее:
Старое поведение:
Сообщение наподобие этого <foo>Band: {{yourName}}</foo> генерирует это xmb-сообщение:
<msg id=123>Name: <ph name=”INTERPOLATION”><ex>{{yourName}}</ex></ph></msg>
Новое поведение:
Сообщение наподобие этого <foo>Band: {{yourName}}</foo> генерирует это xmb-сообщение:
<msg id=123>Name: <ph name=”INTERPOLATION”><ex>{{yourName}}</ex>{{yourName}}</ph></msg>
<Ph> PCDATA (текстовый узел) используется TC для некоторых валидаций.
Исправление ошибок
Bazel
Теперь используется compile_strategy(), чтобы решить, следует ли составлять код Angular с помощью ngc (унаследованный) или ngtsc (локальный). Чтобы правила g3 BUILD правильно переключались и позволяли тестировать Ivy в g3, compile_strategy() стал importable.
Ivy
Функции шаблонов для динамически созданных представлений больше не вкладываются друг в друга. Вместо того, чтобы вкладывать функции и использовать закрытие для получения родительских контекстов, родительские контексты переопределяются явно через инструкцию. Это означает, что мы больше не создаем несколько экземпляров функций для циклов, которые вложены внутри других циклов.
Пример:
<ul *ngFor="let list of lists"> <li *ngFor="let item of list'> {{ item }} {{ name }} </li> </ul>
До:
function AppComponent(rf: RenderFlags, ctx: AppComponent) { // some instructions here function ulTemplate(rf1: RenderFlags, ctx0: any) { // instructions function liTemplate(rf1: RenderFlags, ctx1: any) {...} } }
После:
function ulTemplate(rf: RenderFlags, ctx: any) {...} function liTemplate(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { T(0); } if (rf & RenderFlags.Update) { const item = ctx.$implicit; const comp = x(2); t(0, i2('', item, ' ', comp.name, '')); } } function AppComponent(rf: RenderFlags, ctx: AppComponent) { // some instructions here }
TView.components больше не отслеживают индексы директив (только индексы элементов хоста). Мы можем сократить массив компонентов вдвое, потому что контекст для компонентов теперь хранится в экземпляре компонента LViewData и к нему можно получить доступ.
Теперь у нас есть новая инструкция, reference() (r ()). Раньше мы использовали закрытие, чтобы получить доступ к локальным refs в родительских представлениях. Теперь, когда вложенные функции шаблона являются плоскими; они не имеют доступа к локальным refs через закрытие, поэтому нам нужен другой способ прохождения дерева представлений. reference принимает уровень вложенности, а локальный индекс ref затем просматривает дерево представлений, чтобы найти нужное представление, из которого можно загрузить локальный ref.
До:
function AppComponent(rf: RenderFlags, ctx: AppComponent) { if (rf & RenderFlags.Create) { Ee(0, 'div', null, ['foo', '']); C(2, nestedTemplate, null, [AttributeMarker.SelectOnly, 'ngIf']); } const foo = load(1) as any; function IfTemplate(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { T(0); } if (rf & RenderFlags.Update) { t(0, bind(foo)); } } }
После:
function IfTemplate(rf: RenderFlags, ctx: any) { if (rf & RenderFlags.Create) { T(0); } if (rf & RenderFlags.Update) { const foo = reference(1, 1) as any; t(0, bind(foo)); } } function AppComponent(rf: RenderFlags, ctx: AppComponent) { if (rf & RenderFlags.Create) { Ee(0, 'div', null, ['foo', '']); C(2, nestedTemplate, null, [AttributeMarker.SelectOnly, 'ngIf']); } }
Ядро
Теперь Angular лучше обрабатывает ошибки для @Output, если свойство не инициализировано.
Автор: Valentyn Yakymenko
Источник: https://itnext.io/
Редакция: Команда webformyself.