Angular 模板引用变量是 Angular 框架中一个重要的概念,它可以让我们在模板中使用组件的属性和方法。它可以帮助我们在模板中使用组件的数据,并且可以让我们在模板中使用组件的方法。
Angular 提供了三种不同的引用变量:@Input、@Output 和 @ViewChild。@Input 和 @Output 用于在父子组件之间传递数据;而 @ViewChild 用于获取子组件实例。
// 使用 @Input 在父子组件之间传递数据 @Component({ selector: 'app-child', template: `{{message}}` }) export class ChildComponent { // 获取 message 属性值,该属性值是在父组件注入的 @Input() message: string; constructor() { } } // 使用 @Output 在子组件把数据传递到父组件中去 @Component({ selector: 'app-child', template: `{{message}}` }) export class ChildComponent { // 获取 message 属性值,该属性值是在子组件注入的 @Output() messageChange = new EventEmitter(); constructor() { } // 把信息传递到外部 sendMessage(message) { this.messageChange.emit(message); } }
模板变量可以帮助你在模板的另一部分使用这个部分的数据。使用模板变量,你可以执行某些任务,比如响应用户输入或微调应用的表单。
模板变量可以引用这些东西:
本章包含代码片段的工作实例参阅现场演练 / 下载范例。
在模板中,要使用井号 #
来声明一个模板变量。下列模板变量 #phone
语法在 <input>
元素上声明了一个名为 phone
的变量
<input #phone placeholder="phone number" />
可以在组件模板中的任何地方引用某个模板变量。这里的 <button>
就引用了 phone
变量。
<input #phone placeholder="phone number" />
<!-- lots of other elements -->
<!-- phone refers to the input element; pass its `value` to an event handler -->
<button (click)="callPhone(phone.value)">Call</button>
Angular 根据你所声明的变量的位置给模板变量赋值:
<ng-template>
元素上声明变量,该变量就会引用一个 TemplateRef
实例来代表此模板。#var="ngModel"
,那么该变量就会引用所在元素上具有这个 exportAs
名字的指令或组件。在大多数情况下,Angular 会把模板变量的值设置为它所在的元素。在前面的例子中, phone
引用的是电话号码 <input>
。该按钮的 click 处理程序会把这个 <input>
的值传给该组件的 callPhone()
方法。
这里的 NgForm
指令演示了如何通过引用指令的的 exportAs
名字来引用不同的值。在下面的例子中,模板变量 itemForm
在 HTML 中分别出现了三次。
<form #itemForm="ngForm" (ngSubmit)="onSubmit(itemForm)">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" name="name" ngModel required />
<button type="submit">Submit</button>
</form>
<div [hidden]="!itemForm.form.valid">
<p>{{ submitMessage }}</p>
</div>
如果没有 ngForm
这个属性值,itemForm
引用的值将是 HTMLFormElement 也就是 <form>
元素。而 Component
和 Directive
之间的差异在于 Angular 在没有指定属性值的情况下,Angular 会引用 Component
,而 Directive
不会改变这种隐式引用(即它的宿主元素)。
而使用了 NgForm
之后,itemForm
就是对 NgForm
指令的引用,可以用它来跟踪表单中每一个控件的值和有效性。
与原生的 <form>
元素不同, NgForm
指令有一个 form
属性。如果 itemForm.form.valid
无效,那么 NgForm
的 form
属性就会让你禁用提交按钮。
可以在包含此模板变量的模板中的任何地方引用它。而 结构型指令(如 *ngIf
和 *ngFor
或 <ng-template>
同样充当了模板的边界。你不能在这些边界之外访问其中的模板变量。
同名变量在模板中只能定义一次,这样运行时它的值就是可预测的。
内部模板可以访问外模板定义的模板变量。
在下面的例子中,修改 <input>
中的文本值也会改变 <span>
中的值,因为 Angular 会立即通过模板变量 ref1
来更新这种变化。
<input #ref1 type="text" [(ngModel)]="firstExample" />
<span *ngIf="true">Value: {{ ref1.value }}</span>
在这种情况下,有一个包含这个 <span>
的隐式 <ng-template>
,而该变量的定义在该隐式模板之外。访问父模板中的模板变量是可行的,因为子模板会从父模板继承上下文。
我们用更啰嗦的形式重写上述的代码,可以明确地显示出 <ng-template>
。
<input #ref1 type="text" [(ngModel)]="firstExample" />
<!-- New template -->
<ng-template [ngIf]="true">
<!-- Because the context is inherited, the value is available to the new template -->
<span>Value: {{ ref1.value }}</span>
</ng-template>
但是,从外部的父模板访问本模板中的变量是行不通的。
<input *ngIf="true" #ref2 type="text" [(ngModel)]="secondExample" />
<span>Value: {{ ref2?.value }}</span> <!-- doesn"t work -->
这个更啰嗦的形式表明 ref2
位于外部的父模板中。
<ng-template [ngIf]="true">
<!-- The reference is defined within a template -->
<input #ref2 type="text" [(ngModel)]="secondExample" />
</ng-template>
<!-- ref2 accessed from outside that template doesn"t work -->
<span>Value: {{ ref2?.value }}</span>
考虑下面这个带 *ngFor
的使用范例。
<ng-container *ngFor="let i of [1,2]">
<input #ref type="text" [value]="i" />
</ng-container>
{{ ref.value }}
这里,ref.value
不起作用。结构型指令 *ngFor
将模板实例化了两次,因为 *ngFor
在对数组中的两个条目进行迭代。因此不可能定义出 ref.value
指向的是谁。
对于结构型指令,比如 *ngFor
或 *ngIf
,Angular 也无法知道模板是否曾被实例化过。
结果,Angular 无法访问该值并返回错误。
在 <ng-template>
上声明变量时,该变量会引用一个 TemplateRef
实例来表示该模板。
<ng-template #ref3></ng-template>
<button (click)="log(ref3)">Log type of #ref</button>
在这个例子中,单击该按钮会调用 log()
函数,它把 #ref3
的值输出到控制台。因为 #ref
变量在 <ng-template>
上,所以它的值是一个 TemplateRef
。
下面是一个名为 TemplateRef
的 TemplateRef()
函数在浏览器控制台中展开时的输出。
▼ ƒ TemplateRef()
name: "TemplateRef"
__proto__: Function
模板输入变量是可以在模板的单个实例中引用的变量。你可以用 let
关键字声明模板输入变量,比如 let hero
。
在这个例子中,有几个这样的变量:hero
、i
和 odd
。
<ng-template #hero let-hero let-i="index" let-odd="isOdd">
<div [class]="{"odd-row": odd}">{{i}}:{{hero.name}}</div>
</ng-template>
此变量的范围仅限于可复写模板中的单个实例。可以在其他结构型指令的定义中再次使用相同的变量名。
相反,你可以通过在变量名称前加上 #
来声明模板变量,如 #var
。模板变量引用其附加的元素、组件或指令。
模板输入变量和模板变量名称具有各自的名称空间。let hero
中的模板输入变量 hero
和 #hero
中的模板变量 hero
是不同的。
里程碑5:路由守卫现在,任何用户都能在任何时候导航到任何地方。但有时候出于种种原因需要控制对该应用的不同部分的访问。可能...
添加本地化包要利用Angular的本地化功能,请用AngularCLI将@angular/localize包添加到你的项目中。要添加@angular/localiz...
AngularJS ng-hide 指令 AngularJS 参考手册AngularJS 实例在复选框选中时隐藏一部分:隐藏 HTML: input type="checkbox" ng-mod...
AngularJS ng-mousemove 指令 AngularJS 参考手册AngularJS 实例在鼠标指针在元素上移动时执行表达式:div ng-mousemove="count ...
NPM(Node Package Manger)是一种与社区共享node_modules的方法。package.jsonNPM使用一个名为package.json的简单JSON文件来共...
自定义控制台colors语法高亮可帮助你管理代码的复杂性。colors包(npm install colors)为你的控制台输出带来了类似的好处,使得你...