import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
{{name}}
{{userName.textContent}}
`
})
export class AppComponent {
name:string="Tom";
}
Определение переменной выглядит следующим образом:
{{name}}
Определение переменной userName в элементе параграфа означает, что она будет представлять данный параграф, то есть элемент p разметки html. И далее мы можем обращаться к этому параграфу через данную переменную. Например, через свойство //userName.textContent// можно получить текстовое содержимое параграфа. При этом, если привязанное к параграфу значение переменной name изменится, то соответственно изменится и значение //userName.textContent//:
{{ :angular:angular2:component:2.14.png |}}
При этом данную переменную мы можем использовать только внутри шаблона.\\
\\
Использование шаблонных переменных открывает нам дополнительный способ взаимодействия между родительским и дочерним компонентом. Например, определим следующий дочерний компонент //ChildComponent//:
import { Component} from '@angular/core';
@Component({
selector: 'child-comp',
template: `{{counter}}
`
})
export class ChildComponent{
counter: number = 0;
increment() { this.counter++; }
decrement() { this.counter--; }
}
В этом компоненте определяется переменная счетчика counter. Для ее увеличения или уменьшения применяются методы increment и decrement.\\
\\
В коде главного компонента будем вызывать дочерний компонент:
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
`
})
export class AppComponent { }
В данном случае шаблонная переменная counter, определенная внутри тега ''
import { Component} from '@angular/core';
@Component({
selector: 'my-app',
template: `
`
})
export class AppComponent {
increment() { this.counter++; }
decrement() { this.counter--; }
}
Здесь для класса AppComponent свойства //this.counter// не существует - оно существует только для шаблона.\\
\\
Чтобы все таки иметь возможность обращаться к методам и прочей функциональности дочернего компонента, надо использовать декоратор **ViewChild**. Данный декоратор применяется к свойству и получает селектор элемента DOM, который необходимо отслеживать. И если отслеживаемый по селектору элемент изменяется, то **ViewChild** изменяет состояние свойства. Так, изменим главный компонент следующим образом:
import { Component, ViewChild } from '@angular/core';
import { ChildComponent} from './child.component';
@Component({
selector: 'my-app',
template: `
`
})
export class AppComponent {
@ViewChild(ChildComponent, {static: false})
private counterComponent: ChildComponent;
increment() { this.counterComponent.increment(); }
decrement() { this.counterComponent.decrement(); }
}
Первый параметр декоратора ViewChild указывает на селектор элемента, который будет отслеживаться. В качестве селектора может использоваться класс с декоратором @Component, то есть класс компонента, например, ChildComponent. Второй параметр - static - указывает, как будет производиться отслеживание изменений.
====Привязка ViewChild к шаблонным переменным====
Несмотря на то, что выше мы не использовали переменные, тем не менее с помощью декоратора ViewChild также можно связать свойство и переменную из шаблона. Так, изменим код главного компонента:
import { Component, ViewChild, ElementRef } from '@angular/core';
@Component({
selector: 'my-app',
template: `{{name}}
{{nameText.textContent}}
`
})
export class AppComponent {
@ViewChild("nameText", {static: false})
nameParagraph: ElementRef;
name: string = "Tom";
change() {
console.log(this.nameParagraph.nativeElement.textContent);
this.nameParagraph.nativeElement.textContent = "hell";
}
}
Здесь в шаблоне определяется переменная nameText, которая представляет код параграфа. А в декоратор ViewChild передается имя этой переменной. Поэтому свойство nameParagraph, к которому применяется декоратор, будет указывать на эту переменную nameText. Причем свойство nameParagraph представляет тип ElementRef, который используется для ссылки на элементы html.\\
\\
По нажатию на кнопку выводится и изменяется текстовое содержимое этой переменной.
====ContentChild====
Кроме //ViewChild// для связи с шаблонными переменными мы можем применять другой декоратор - **ContentChild**, который работает похожим образом. В какой ситуации он может понадобится? Допустим, в родительском компоненте определен следующий код:
import { Component} from '@angular/core';
@Component({
selector: 'my-app',
template: `
Добро пожаловать {{name}}!
`
})
export class AppComponent {
name: string = "Tom";
}
Здесь определена переменная //#headerContent//, которая указывает на элемент заголовка h3.\\
\\
Причем поскольку данные из родительского компонента передаются в дочерний напрямую, то для получения этих данных в дочернем компоненте будет использоваться элемент //ng-content//:
import { Component, ContentChild, ElementRef } from '@angular/core';
@Component({
selector: 'child-comp',
template: `
`
})
export class ChildComponent{
@ContentChild("headerContent", {static:false})
header: ElementRef;
change() {
console.log(this.header);
this.header.nativeElement.textContent = "Hell to world!";
}
}
И как раз чтобы получить переменные, которые передаются с кодом через ng-content, дочерний компонент применяет декоратор **ContentChild**. В этот декоратор также передается название переменной. Само свойство декоратора также представляет объект ElementRef. И далее мы можем манипулировать этим объектом.