4、Angular 2模板语法

本文详细介绍Angular框架中的核心特性,包括插值语法、双向数据绑定、结构型指令与属性型指令的使用方法,以及如何自定义管道等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  在使用angular/cli创建的新项目中,先将css的预编译器改为scss(将所有已.css为后缀的文件都改为.scss为后缀;同时将其他文件中对css文件的引用也都改为.scss)。随后导入bootstrap和font-awesome的依赖包(在package.json中添加这两个依赖包,然后运行cnpm install命令即可)。随后可以做对应的语法测试。

插值语法

也就是典型的{{}}获取值的方法
如图,代码中声明变量和方法:
这里写图片描述

然后再html模板文件中使用:

最后显示的样子如下:
image

在模板内部定义局部变量

使用#符号,在html模板中定义局部变量,然后再html模板中使用。(组件类的ts代码中也是可以引用到的,但是需要使用到element-ref什么的,先不管)。
代码中声明:
这里写图片描述
html模板中使用#符号:

html模板中使用

浏览器中显示:
这里写图片描述
这里写图片描述

值绑定、事件绑定、双向绑定

Angular 1.x的时候,数据绑定都是使用的model。但是在Angular 2中有区分:
- 值绑定:使用[]
- 事件绑定:使用()
- 双向绑定:使用[()]

单向值绑定

这里写图片描述

这里写图片描述

事件绑定

这里写图片描述

这里写图片描述

双向绑定

ngModel

ngModel可以用作数据绑定,但是只能用在表单元素上,类似于之类的添加一个ngModel指令就可以了。

使用[()]完成双向绑定

最后浏览器显示如下:子模块中文字字体大小变动可以同步到父组件中的文字 字体

这里写图片描述
首先,子组件中的代码如下:

这里写图片描述

这里写图片描述

这里写图片描述
然后,父组件中代码如下:使用子组件标签时,使用[()]将子组件类中的size属性双向绑定上父组件中的fontSizePx属性,然后子组件修改size之后,父组件的fontSizePx同步修改,做到双向数据绑定。

这里写图片描述

这里写图片描述

[()]补充:

上面没有写得很清楚,子控件在触发方法修改双重绑定的那个值时,需要将@Output中定义的对应”属性Change”事件进行emit。

下面是后面在网上查询到的:

那么,如何通过[()]在我们自定义的指令上实现双向绑定呢?没错,就是使用@Input和@Output来实现。

//父组件
@Component({
    selector: 'my-app',
    template: `
<customer-counter [(counter)] = "someValue"></customer-counter>
<p> value: {{someValue}}</p>
`,
    directives:[CustomerCounterComponent]
})

export class AppComponent{
    someValue = 3;
}
//子组件
@Component({
    selector: 'customer-counter',
    template: `
    <button (click)="decrement()">-</button>
    <span>{{counter}}</span>`
})

export class CustomerCounterComponent{
    counterValue = 0;
    @Input()
    get counter(){
        return this.counterValue;
    }
    @Output() counterChange = new EventEmitter();
    set counter(val) {
        this.counterValue = val;
        // 这里,方法中需要在值改动的时候,将对应的值改变事件emit出去,让父组件能够接收到。
        this.counterChange.emit(this.counterValue);
    }

    // 这个方法修改值,会调用值对应的setter方法(在setter方法中对事件进行了emit)
    decrement() {
        this.counter--;
    }
}

这样<customer-counter [(counter)] = "someValue"></customer-counter>就可以将父组件中的someValue绑定到子组件的counter属性上,同时当子组件的counter属性发生改变时也更新父组件的someValue值。

需要注意的是,我们定义的事件监听是counterChange,而使用的却是[(counter)]。

这是因为Angular 2中约定添加后缀Change,也就是[(counter)]等价于[change]和(counterChange)的组合。如果去看[(ngModel)]的实现,你也会发现它是[ngModel]和[ngModelChange]的组合。

内置结构型指令

结构型指令不可以在同一个标签中使用多个,只能用一个。解决方法就是多加一层div,用另一个指令。

*ngIf

<p *ngIf="isShow">是否显示</p>

*ngFor

*ngFor只能迭代数组,不能迭代一个对象中的属性。

<li *ngFor="let race of races;let i=index;">
    {{i+1}}-{{race.name}}
</li>

ngSwitch

<div [ngSwitch]="mapStatus">
    <p *ngSwitchCase="'下载中'">下载中...</p>
    <p *ngSwitchCase="'正在读取'">正在读取...</p>
    <p *ngSwitchDefault>系统繁忙</p>
</div>

内置属性型指令

NgClass

对应的css类会被加到对应的标签去,然后标签就有了这些类对应的样式。

<div [ngClass]="currentClasses">同时批量设置多个class</div>

<!--然后组件类中,设置currentClasses,设置为多个已经预先定义在scss文件中的类:-->
currentClasses = {
    'saveable': this.canSave, // 后面这个值是一个bool,用来设置是否需要加上前面这个类
    'modified': this.isUnchanged,
    'special': this.isSpecial
};

NgStyle

与ngClass类似,但是ngStyle是直接写样式,而不是使用css类声明样式(这是不推荐的!)。使用方法也是一样的,在标签中对ngStyle使用值绑定到某个属性中:

<div [ngStyle]="currentStyles">
    用ngStyle批量修改内联样式
</div>

<!--然后在组件类中,设置对应的变量,写对应的内联样式-->
currentStyles = {
    'font-style': this.canSave ? 'italic' : 'normal',
    'font-weight': this.isUnchanged ? 'bold' : 'normal',
    'font-size': this.isSpecial ? '24px' : '12px'
};

NgModel

ngModel只能用在表单控件中,它是用来进行数据的双向绑定的,将ngModel使用[(ngModel)]双重数据绑定到组件类中的属性中即可:

<!--在组件类中声明属性-->
public currentRace: Any = {name: "随机种族"};

<!--在html模板中使用ngModel进行双向绑定-->
<input [(ngModel)]="currentRace.name">
<p>{{currentRace.name}}</p><!--这里就会随着input框的输入变化而变化,这就是双向数据绑定-->

需要使用ngModel的话,需要在app.module.ts这个应用根模块中import对应的表单模块才行,否则无法使用:import {FormsModule} from '@angular/forms';在imports节点中的数组中也添加上FormsModule

几个小工具

管道

管道是用来格式化字符串的,下面在页面中显示时间随着一秒一秒地跳动,同时使用管道将国际时间显示方式格式化为我们习惯的看法:

<!--首先在组件类中声明需要绑定的变量,然后设置变量一秒一变-->
export class TestPipeConponent implements OnInit {
    public currentTime: Date = new Date();

    construct() {

    }

    ngOnInit() {
        // 在Init中每一秒钟给currentTime属性赋一个最新的值,让界面绑定的值会一秒一秒变动
        window.setInterval(
            // 这里使用了箭头函数,this指代了本类的实例,而不是指代本函数,这是箭头函数的好处
            () => {this.currentTime = new Date()}
            , 1000);
    }
}

<!--然后在html模板中绑定上对应的属性,并且将属性使用管道进行格式化,date是系统内置的一个管道-->
<p>{{currentTiem | date:'yyyy-MM-dd HH:mm:ss'}}</p>

系统内置有12个管道:

这里写图片描述

自定义管道

需要自定义管道的话,要自定义类实现对应接口,如下

/**
 ** 新建boolean-pipe.ts文件
 **/
import {Pipe, PipeTransform} from '@angular/core'; // import相关东西

// 使用装饰器,告诉angular编译器这是个Pipe
@Pipe({
    name: 'boolean'   // 名字是什么,后面使用这个管道的时候就用这个名字
})

// 类,需要实现PipeTransform,它又一个transform方法需要实现
export class BooleanPipe implements PipeTransform {
    constructor() {

    }

    // 必须实现这个方法
    transform(flag: string): string {
        return flag==="true" ? "text-danger" : ""; 
    }
}

/**
 * 如何使用这个管道
 **/
// 在需要使用这个管道的模块比如是post.module.ts文件中,import这个管道
import { BooleanPipe } from '../utils/boolean-pipe';

管道还有国际化的作用。

安全导航

安全导航就是一个语法糖,通过使用一个?,来告诉编译器,当我访问一个类的属性的时候,不管这个属性是否有定义,你都不要给我抛异常,如果属性未定义,你就直接不要显示就好了。

<p>当前选中的人种{{currentRace?.name}}</p>

<!--这种情况,如果在组件类中没有声明name这个属性的时候,angular编译器不会报错,而是会直接什么都不显示-->

非空断言

用得比较少

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值