Web-Angular的Templates模板

模板(Templates)

        在上面关于组件的讨论中,我们看到模板是一个字符串,用于指定在组件的视图区域中显示的内容。我们看到这个字符串主要是HTML代码,但也包含特定的Angular语法,运行时系统将其转换为纯HTML代码,插入到DOM中。Angular语法分为几个不同的部分,我们将逐个进行介绍。

        第一组是生成要插入到HTML代码中的字符串的表达式。这些包括我们之前看到的’{ {‘和’}}'语法。主要有以下四种类型:

  1. { {expression}} 将任何类似于TypeScript的表达式包围起来,该表达式返回一个要插入到HTML代码中的字符串。Angular将此称为插值(interpolation)。该表达式受限于访问当前的Angular上下文,通常是它所在的组件。这个表达式并不是完整有效的TypeScript。

  2. [target] = “expression” 将类似于TypeScript的表达式的值分配给目标属性。

  3. (event) = “statement” 指定将事件处理程序分配给事件。Angular将其称为模板语句。

  4. [(target)]= “expression” 将表达式的值分配给目标,并反过来也是如此。当程序可以更改值(例如文本字段),用户可以通过与浏览器交互来更改相同的值时,会使用此功能。这被称为双向赋值。

        这三个赋值表达式必须小心使用。它们是动态代码,只要右侧发生变化,就会更新Angular对象。一个常见错误是忘记使用方括号或括号,例如,以下两个模板代码是完全不同的。

<img src="imageurl"/>
<img [src]="imageurl"/>

        第一个代码定义了一个带有HTML属性的标签,该属性被初始化为给定的字符串。第二个代码中,目标是一个Angular对象属性,它被赋值为该字符串。在第二个示例中,如果Angular属性发生变化,则显示的图片也会发生变化。这与第一个示例不同,第一个示例中属性只用于初始化DOM。

        最后一点是一个重要的区别:Angular语句读取并更新DOM对象的属性。HTML属性仅在页面加载时用于初始化DOM。这些属性和属性可能具有相同的名称,但它们只在初始化时具有相同的值,直到属性被JavaScript或Angular更改。

        还要注意,这些语句中引用的对象必须是组件的局部对象。您无法访问全局变量。例如,无法在这些语句中使用console.log(),因为console是一个全局变量。但是,您可以通过将访问放置在组件的成员函数中来访问一些全局对象(例如console.log())。例如,可以在模板中为某个HTML元素编写点击事件:

(click)="doClick()"

        然后在组件类定义中,我们可以定义事件处理程序:

doClick(): void {
  ... // 代码执行的内容
  console.log("clicked");
}

        我们将使用一个简单的示例演示上面的四个表达式。目标是生成以下应用程序显示效果(在交互之前和之后)。

        在此应用程序中,文本字段允许输入,输入的内容将在文本字段上方的文本中显示出来。当用户点击页面上的“Click me!”段落时,它的颜色将发生变化。左侧的图片是加载时的初始视图,右侧的图片是在文本字段中输入“hello”并点击“Click me!”段落一次后的应用程序视图。

        组件的代码如下所示:

@Component({
  selector: 'app-root',
  template: `<h1>Hello World</h1>
             <p>Welcome to Angular</p>
             <p>Name: {
   
   {name}}</p>
             <input [(ngModel)]="name" placeholder="type here"/>
             <p (click)="doClick()" [class.selected]="clicked">Click me! </p>`,
  styles: [`.selected { color: red; }`]
})
export class AppComponent {
  name: string;
  clicked = false;

  doClick(): void {
    this.clicked = !this.clicked;
  }
}

        关于这段代码需要注意以下几点:

  1. 上述代码在没有导入Angular的Forms模块时无法运行。在下一节中,我们将看到如何导入该模块以支持标签。
  2. 我们向组件引入了样式。这些样式定义将应用于视图区域。在这种情况下,我们引入了一个名为selected的样式,用于处理可点击段落。
  3. 标签定义了文本输入区域。Angular的双向绑定链接了文本输入字段和组件类中名为name的字段。这确保每当用户更改文本输入字段(逐个字符)时,组件字段都会得到更新,反之亦然。ngModel标识符是对输入字段文本值的Angular引用。
  4. 可点击段落有一个定义在

    标签内容中的事件处理程序。这定义了一个函数作为事件处理程序,您将在AppComponent类中看到其定义。我们还可以将样式定义为单独的源文件,并使用stylesUrl属性而不是内联样式定义。

  5. 同样的

    标签具有一个单向绑定,根据组件中名为clicked的布尔属性切换选择的样式(在上面的样式属性中定义)。在阅读后面的内容时,您将看到此属性由事件处理程序切换。这是通过使用特殊词“class”来访问与HTML元素关联的样式类来实现的。您还可以使用特殊词“style”来访问单个样式,而不是样式类。

        以下是代码块中的内容:

<div *ngIf="specialColour=='red'" style="color:red"> Danger!</div>

<span [ngSwitch]="specialColour">
  <span *ngSwitchCase="'red'">Danger</span>
  <span *ngSwitchCase="'green'">Nice</span>
  <span *ngSwitchCase="'blue'">Sky</span>
  <span *ngSwitchDefault>no opinion</span>
</span>

<ul>
  <li *ngFor="let col of colourList">{
   
   {col}}</li>
</ul>

        另外,还有一种可放置在 Angular 模板中的 Angular 表达式的类型。它们被称为模板语句,相当于常规编程语言中的控制语句,但这些语句适用于视图而不是代码。存在与传统语言中的 if、for 和 switch 语句等效的语句。

        第一个语句是 *ngIf 语句,如果关联的表达式为真,则包括该元素。例如,请考虑以下语句。

<div *ngIf="specialColour=='red'" style="color:red"> Danger!</div>

        你可以看到,在这里,*ngIf 用作

        标签的属性。它以一个 TypeScript 表达式作为其值。它通过在表达式为真时将标签的内容包含在 DOM 中,而在表达式为假时则不包含。请注意,这与使用样式更改隐藏显示的文本(例如,隐藏的样式类)不同。*ngIf 实际上在表达式为假时从 DOM 中删除数据,这对于复杂数据而言具有重要的性能优势。

        下一个 Angular 模板语句是 ngSwitch 语句。它允许我们根据 switch 语句的值指定要显示的备选值。它是 *ngIf 的更灵活版本,测试的值不仅仅是 true 和 false。

        看下面的例子。

<span [ngSwitch]="specialColour">
  <span *ngSwitchCase="'red'">Danger</span>
  <span *ngSwitchCase="'green'">Nice</span>
  <span *ngSwitchCase="'blue'">Sky</span>
  <span *ngSwitchDefault>no opinion</span>
</span>

        请注意,有三个关键字(ngSwitch、*ngSwitchCase 和 *ngSwitchDefault)。不寻常的关键字是 ngSwitch,它以括号形式作为 Angular 赋值语句出现。从你以前的编程经验来看,应该很容易理解此代码的 switch 部分的工作原理。还请注意,双引号是必需的,例如 " ‘red’"。这是因为该属性由 HTML 定义,而 Angular 编译器扫描的是该属性的内容作为 TypeScript 字符串。因为它是 TypeScript 字符串,所以它也需要第二组引号。

        最后,最复杂的 Angular 语句是 *ngFor。它定义了一个循环,用于处理对象集合,例如数组。我们将通过示例演示此语句。假设我们有以下组件定义。

export class AppComponent {
  colourList = ["red", "white", "blue", "black", "green"];
  specialColour = 'green';
}

        这引入了一个字符串数组,我们可以使用 *ngFor 语句处理。以下组件描述将按列表形式显示数据。它还演示了我们上面使用的 *ngIf 语句。

@Component({
  selector: 'app-root',
  template: `<h1>List of colours</h1>
             <div *ngIf="specialColour=='red'" style="color:red"> Danger!</div>
             <ul>
             <li *ngFor="let col of colourList">{
   
   {col}}</li>
             </ul>
            `,
})

        这将在浏览器中显示如下。

        我们还可以使用一些额外的语法来访问数组的索引号。例如,如果我们想在上面的例子中在数组值之前打印索引号,那么我们可以这样写:

<ul>
  <li *ngFor="let col of colourList; let i=index" style="list-style-type:none">{
   
   {i}}: {
   
   {colourList[i]}}</li>
</ul>

        这将显示如下:

        很遗憾,我们不能仅使用索引语法,您必须在循环字符串中添加 “let-of” 才能识别索引的赋值。

猜你喜欢

转载自blog.csdn.net/qq_54813250/article/details/133790944
今日推荐