Шаблонные переменные, ViewChild и ContentChild¶
Шаблонные переменные позволяют определить некоторые переменные внутри шаблона компонента и затем ссылаться к этим переменным из этого же шаблона. Для определения подобных переменных применяется знак решетки (#). Например, определим шаблонную переменную userName в компоненте:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Определение переменной выглядит следующим образом:
1 | |
Определение переменной userName в элементе параграфа означает, что она будет представлять данный параграф, то есть элемент p разметки html. И далее мы можем обращаться к этому параграфу через данную переменную. Например, через свойство userName.textContent можно получить текстовое содержимое параграфа. При этом, если привязанное к параграфу значение переменной name изменится, то соответственно изменится и значение userName.textContent:
При этом данную переменную мы можем использовать только внутри шаблона.
Использование шаблонных переменных открывает нам дополнительный способ взаимодействия между родительским и дочерним компонентом. Например, определим следующий дочерний компонент ChildComponent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
В этом компоненте определяется переменная счетчика counter. Для ее увеличения или уменьшения применяются методы increment и decrement.
В коде главного компонента будем вызывать дочерний компонент:
1 2 3 4 5 6 7 8 9 10 11 | |
В данном случае шаблонная переменная counter, определенная внутри тега <child-comp>, поэтому она будет представлять компонент ChildComponent.
Соответственно далее мы можем ссылаться к компоненту ChildComponent через эту переменную, например, установить для событий кнопок привязку к методам ChildComponent. В итоге по нажатию на кнопки в главном компоненте будут вызываться методы из дочернего компонента:
ViewChild¶
Однако шаблонные переменные имеют свои ограничения: они не могут применяться вне шаблона, даже в коде класса компонента. Например, мы не можем написать так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Здесь для класса AppComponent свойства this.counter не существует — оно существует только для шаблона.
Чтобы все таки иметь возможность обращаться к методам и прочей функциональности дочернего компонента, надо использовать декоратор ViewChild. Так, изменим главный компонент следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
С помощью применения к нему декоратора ViewChild к свойству counterComponent мы устанавливаем, что это свойство будет содержать объект дочернего компонента, который внедряется через элемент <child-comp></child-comp>. И в этом случае мы уже можем не использовать шаблонные переменные в шаблоне.
Привязка ViewChild к шаблонным переменным¶
Несмотря на то, что выше мы не использовали переменные, тем не менее с помощью декоратора ViewChild также можно связать свойство и переменную из шаблона. Так, изменим код главного компонента:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | |
Здесь в шаблоне определяется переменная nameText, которая представляет код параграфа. А в декоратор ViewChild передается имя этой переменной. Поэтому свойство nameParagraph, к которому применяется декоратор, будет указывать на эту переменную nameText. Причем свойство nameParagraph представляет тип ElementRef, который используется для ссылки на элементы html.
По нажатию на кнопку выводится и изменяется текстовое содержимое этой переменной.
ContentChild¶
Кроме ViewChild для связи с шаблонными переменными мы можем применять другой декоратор — ContentChild. В какой ситуации он может понадобится? Допустим, в родительском компоненте определен следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
Здесь определена переменная #headerContent, которая указывает на элемент заголовка h3.
Причем поскольку данные из родительского компонента передаются в дочерний напрямую, то для получения этих данных в дочернем компоненте будет использоваться элемент ng-content:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
И как раз чтобы получить переменные, которые передаются с кодом через ng-content, дочерний компонент применяет декоратор ContentChild. В этот декоратор также передается название переменной. Само свойство декоратора также представляет объект ElementRef. И далее мы можем манипулировать этим объектом.

