이 글에서는 angular10 템플릿의 데이터 바인딩을 소개하고 세 가지 바인딩 구문, 템플릿/보간 표현식, 속성 바인딩, 스타일 바인딩, 이벤트 바인딩, 양방향 바인딩, 내장 지시문, 템플릿을 안내합니다. 참조 변수 등.
바인딩 구문 개요
바인딩 구문은 세 가지 유형으로 요약할 수 있습니다(기본)
- model => 뷰(단방향: 보간, 속성 바인딩, 스타일 바인딩)
- view => 모델(단방향: 이벤트 바인딩)
- view 모델(양방향: ngModule)
【관련 튜토리얼 추천: "angular tutorial"】
<!-- model => view --> {{expression}} [target]="expression" bind-target="expression" <p> {{ msg }} </p> // 插值表达式 <img src="/static/imghwm/default1.png" data-src="../assets/images/madao.jpg" class="lazy" [src]="heroImageUrl" alt="Angle10에서 템플릿에 데이터 바인딩을 수행하는 방법에 대해 이야기해 볼까요?" > // 属性绑定 <app-hero-detail [hero]="currentHero"></app-hero-detail> // 组件通过属性绑定的方式传参 <div [ngClass]="{'special': isSpecial}"></div> // 样式绑定 <div [class.special]="isSpecial">Special</div> // class绑定 <button [style.color]="isSpecial ? 'red' : 'green'"> // style绑定 <button [attr.aria-label]="help">help</button> // Attribute绑定 <!-- view => model --> (target)="statement" on-target="statement" <button (click)="onSave()">Save</button> // 元素事件 <app-hero-detail (deleteRequest)="deleteHero()"></app-hero-detail> // 组件事件,用于监听子组件传递过来的参数 <div (myClick)="clicked=$event" clickable>click me</div> // 指令事件 <!-- view <=> model --> [(target)]="expression" bindon-target="expression" <input [(ngModel)]="name"> // 双向数据绑定
HTML 속성과 DOM 속성 비교(매우 중요, 이해 강화)
HTML 속성과 DOM 속성의 차이점을 이해하는 것은 Angular 바인딩 작동 방식을 이해하는 열쇠입니다. 속성은 HTML로 정의됩니다. 속성은 DOM(문서 개체 모델) 노드에서 액세스됩니다.
- 일부 HTML 속성은 속성에 1:1로 매핑될 수 있습니다(예: "id").
- 일부 HTML 속성에는 해당 속성이 없습니다. 예를 들어 aria-* colSpan rowSpan입니다.
- 일부 DOM 속성에는 해당 속성이 없습니다. 예를 들어 textContent입니다.
HTML 속성과 DOM 속성은 이름이 같더라도 다르다는 점을 기억하는 것이 중요합니다. Angular에서 HTML 속성의 유일한 목적은 요소와 지시문의 상태를 초기화하는 것입니다.
템플릿 바인딩은 속성 대신 속성과 이벤트를 사용합니다.
데이터 바인딩을 작성할 때 대상 개체의 DOM 속성과 이벤트만 처리하게 됩니다.
참고:
이 일반 규칙은 HTML 속성 및 DOM 속성의 정신적 모델을 구축하는 데 도움이 될 수 있습니다. 속성은 DOM 속성을 초기화한 다음 마무리하는 역할을 담당합니다. 속성 값은 변경될 수 있지만 속성 값은 변경될 수 없습니다.
이 규칙에는 한 가지 예외가 있습니다. 속성은 setAttribute()를 통해 변경될 수 있으며, 그러면 해당 DOM 속성이 다시 초기화됩니다.
사례 1: 입력
<input type="text" value="Sarah">
브라우저가 입력을 렌더링할 때 속성 값이 "Sarah"로 초기화된 해당 DOM 노드를 생성합니다.
사용자가 입력에 Sally를 입력하면 DOM 요소의 Property 값이 Sally가 됩니다. 그러나 input.getAttribute('value')를 사용하여 HTML의 속성 값을 보면 속성이 변경되지 않고 남아 있음을 볼 수 있습니다. 이는 Sarah를 반환합니다.
HTML의 value 속성은 초기 값을 지정합니다. DOM의 값은 이 속성이 현재 값이라는 것입니다.
사례 2: 비활성화된 버튼
disabled 속성이 또 다른 예입니다. 버튼의 비활성화된 속성은 기본값이 false이므로 버튼이 활성화됩니다.
disable 속성을 추가하면 그 존재만으로도 버튼의 비활성화 속성이 true로 초기화되어 버튼이 비활성화됩니다.
<button disabled>Test Button</button>
비활성화된 속성을 추가하고 제거하면 버튼이 비활성화되고 활성화됩니다. 그러나 Attribute 값은 중요하지 않으므로 stilldisabled라고 작성하여 이 버튼을 활성화할 수 없습니다.
버튼 상태를 제어하려면 비활성화된 속성을 설정하세요.
<input [disabled]="condition ? true : false"> <input [attr.disabled]="condition ? 'disabled' : null">
템플릿/보간 표현식 {{}}(기본, 마스터리)
변수 바인딩 외에도 템플릿의 메서드 바인딩도 가능합니다
판단이나 연산 같은 간단한 로직을 작성할 수도 있습니다
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <p>变量绑定:{{ title }}</p> <p>方法绑定:{{ getVal }}</p> <p>方法绑定:{{ getVal2() }}</p> <p>简单运算 {{ 1 + 1 }}.</p> <p>简单运算 {{ price * 0.7 }}.</p> <p>简单运算:{{ gender === 0 ? '男':'女' }}</p> <p>与方法结合 {{ price * 0.7 + getVal }}.</p> <p>与方法结合 {{ price * 0.7 + getVal2() }}.</p> `, }) export class AppComponent { title = "模板绑定"; price = 30; gender = 0; get getVal(): number { //es6新语法,函数可以当做变量来使用 return 20; } getVal2(): number { return 33; } }
템플릿 표현식을 사용할 때 다음 지침을 따르세요.
- 매우 간단함
- 빠르게 실행됩니다
- 눈에 보이는 부작용이 없습니다(예: 템플릿의 로직 변경할 수 없음 구성요소 변수)
속성 바인딩(기본, 마스터리)
그림 바인딩
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <img src="/static/imghwm/default1.png" data-src="../assets/images/madao.jpg" class="lazy" alt="madao" /> <img src="/static/imghwm/default1.png" data-src="madaoSrc" class="lazy" [src]="madaoSrc" alt="madao" /> // 推荐 <img src="/static/imghwm/default1.png" data-src="madaoSrc" class="lazy" bind- alt="madao" /> `, styles: [] }) export class AppComponent { madaoSrc = '../assets/images/madao.jpg'; }
일반 속성 바인딩
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <img src="/static/imghwm/default1.png" data-src="{{ user.pic }}" class="lazy" [src]="user.pic" [alt]="user.name" /> <table class="table-bordered"> <tr> <th>name</th> <th>phone</th> <th>age</th> </tr> <tr> <td>张三</td> <td>13398490594</td> <td>33</td> </tr> <tr> <td [colSpan]="colSpan">李四</td> // 注意colSpan和colspan <td>15079049984</td> <td>22</td> </tr> </table> <button class="btn btn-primary" [disabled]="isDisabled">click</button> `, styles: [] }) export class AppComponent { madaoSrc = '../assets/images/madao.jpg'; user = { name: 'madao', pic: this.madaoSrc }; colSpan = 2; isDisabled = false; }
사용자 정의 속성 바인딩
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <span [attr.data-title]="customTitle">一行文字</span> <span [attr.title]="customTitle">test title</span> <span [title]="customTitle">test title</span> `, styles: [] }) export class AppComponent { madaoSrc = '../assets/images/madao.jpg'; customTitle = 'bbb'; }
보간법 사용 식 수식( 권장하지 않음)
속성에 보간을 사용할 수도 있지만 일반적으로 대괄호 []를 사용하는 것이 좋습니다. 전체 프로젝트가 통일된 스타일을 유지하는 것이 좋습니다
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <img src="/static/imghwm/default1.png" data-src="{{ user.pic }}" class="lazy" alt="{{ user.name }}" /> `, styles: [] }) export class AppComponent { madaoSrc = '../assets/images/madao.jpg'; user = { name: 'madao', pic: this.madaoSrc }; }
스타일 바인딩(속성 바인딩에 속함) , 기본, 마스터링)
단일 스타일 바인딩
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <button type="button" class="btn" [class.btn-primary]="theme === 'primary'">Primary</button> <button type="button" class="btn" [class.btn-secondary]="true">secondary</button> <button type="button" class="btn" [class.btn-success]="isSuccess">success</button> <button type="button" class="btn" [class.btn-danger]="'啦啦啦'">danger</button> <button type="button" class="btn" [class.btn-danger]="0">danger</button> //false <button type="button" class="btn" [class.btn-danger]="undefined">danger</button> //false `, styles: [] }) export class AppComponent { theme = 'primary'; isSuccess = true; }
여러 클래스 바인딩
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <button type="button" [class]="btnCls">btnCls</button> <button type="button" [class]="btnCls2">btnCls2</button> <button type="button" [class]="btnCls3">btnCls3</button> <!-- 也可以用内置指令ngClass --> <button type="button" [ngClass]="btnCls">btnCls</button> <button type="button" [ngClass]="btnCls2">btnCls2</button> <button type="button" [ngClass]="btnCls3">btnCls3</button> `, styles: [] }) export class AppComponent { btnCls = 'btn btn-primary'; btnCls2 = ['btn', 'btn-success']; btnCls3 = { btn: true, 'btn-info': true }; }
단일 스타일 바인딩
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <p [style.color]="'#f60'">一段文字</p> <p [style.height]="'50px'" [style.border]="'1px solid'">设置高度</p> <p [style.height.px]="50" [style.border]="'1px solid'">设置高度</p> `, styles: [] }) export class AppComponent {}
여러 스타일 바인딩
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <p [style]="style1">style1</p> <p [style]="style2">style2</p> <p [style]="style3">style3</p> <!-- 也可以用内置指令ngStyle, 但不推荐,以后可能会弃用 --> <!-- <p [ngStyle]="style1">style1</p>--> <!-- <p [ngStyle]="style2">style2</p>--> <!-- ngStyle只接收对象 --> <p [ngStyle]="style3">style3</p> `, styles: [] }) export class AppComponent { style1 = 'width: 200px;height: 50px;text-align: center;border: 1px solid;'; style2 = ['width', '200px', 'height', '50px', 'text-align', 'center', 'border', '1px solid']; // 有问题 style3 = { width: '200px', height: '50px', 'text-align': 'center', border: '1px solid' }; }
바인딩 우선순위
- 클래스 또는 스타일 바인딩이 더 구체적일수록 우선순위가 높아집니다.
- 바인딩은 항상 정적 속성보다 우선합니다.
이벤트 바인딩(기본, 마스터리)
기본 사용법
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <button type="button" class="btn btn-primary" (click)="onClick()">Primary</button> `, styles: [] }) export class AppComponent { onClick() { console.log('onClick'); } }
事件对象
$event 就是原生的事件对象
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <button type="button" class="btn btn-primary" (click)="onClick($event)">Primary</button> `, styles: [] }) export class AppComponent { onClick(event: MouseEvent) { console.log('onClick', event.target); //直接用event.target.value会报错,要用类型断言 console.log((event.target as HTMLInputElement).value) } }
事件捕获或事件冒泡
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <div style="width:200px;height:200px;background-color:red;" (click)="parentClick()"> <!--<div style="width:100px;height:100px;background-color:blue;" (click)="chilrenClick($event)"></div>--> <div style="width:100px;height:100px;background-color:blue;" (click)="$event.stopPropagation()"></div> //可以在html使用一些简单的语法 </div> `, styles: [] }) export class AppComponent { parentClick() { console.log('parentClick'); } chilrenClick(event: MouseEvent) { event.stopPropagation(); //阻止事件冒泡 console.log('chilrenClick'); } }
输入输出属性(主要是子传父,通过自定义事件)
输入属性
子组件
import { Component, Input } from '@angular/core'; @Component({ selector: 'app-root', template: `<p> Today's item: {{item}} </p>` }) export class ItemDetailComponent { @Input() item: string; }
父组件
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <app-item-detail [item]="currentItem"></app-item-detail> `, }) export class AppComponent { currentItem = 'Television'; }
输出属性
- 通过 new EventEmitter() 自定义一个事件;
- 调用 EventEmitter.emit(data) 发出事件,传入数据;
- 父指令通过监听自定义事件,并通过传入的 $event 对象接收数据。
子组件
import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-root', template: `<label>Add an item: <input #newItem></label> <button (click)="addNewItem(newItem.value)">Add to parent's list</button>`, }) export class ItemOutputComponent { @Output() newItemEvent = new EventEmitter<string>(); //子传父,输出属性 addNewItem(value: string) { this.newItemEvent.emit(value); //自定义事件触发 } }
父组件
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <app-item-output (newItemEvent)="addItem($event)"></app-item-output> //监听自定义事件 `, }) export class AppComponent { items = ['item1', 'item2', 'item3', 'item4']; addItem(newItem: string) { this.items.push(newItem); } }
在元数据中声明输入和输出属性
固然可以在 @Directive 和 @Component 元数据中声明 inputs 和 outputs,但不推荐提供别名
@Input()和@Output()可以接收一个参数,作为变量的别名,那么父组件中只能用别名绑定
子组件
import { Component, Input, EventEmitter, Output } from '@angular/core'; @Component({ selector: 'app-root', template: `<p> Today's item: {{item}} </p>` }) export class ItemDetailComponent { @Input('aliasItem') item: string; @Output('newItem') newItemEvent = new EventEmitter<string>(); addNewItem(value: string) { this.newItemEvent.emit(value); } }
父组件
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <app-item-detail [aliasItem]="currentItem" //注意是绑定的别名 (newItem)="addItem($event)"></app-item-detail> //注意是监听的别名 `, }) export class AppComponent { currentItem = 'Television'; items = ['item1', 'item2', 'item3', 'item4']; addItem(newItem: string) { this.items.push(newItem); } }
输入属性一定要用中括号[]绑定?
如果绑定的值是静态的,就不需要[];为了统一风格尽量用上[]
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <app-item-detail item="static item"></app-item-detail> `, }) export class AppComponent { // currentItem = 'Television'; }
双向绑定(基础,掌握)
先决条件
- 组件的属性绑定
- 组件的事件绑定
- 输入和输出(父子组件通信)
基本的双向绑定
子组件
import {Component, OnInit, ChangeDetectionStrategy, EventEmitter, Input, Output} from '@angular/core';@Component({ selector: 'app-sizer', template: ` <div> <button class="btn btn-danger" (click)="dec()" title="smaller">-</button> <button class="btn btn-primary" (click)="inc()" title="bigger">+</button> <label [style.font-size.px]="size">FontSize: {{size}}px</label> </div> `, styles: [ ], changeDetection: ChangeDetectionStrategy.OnPush })export class SizerComponent implements OnInit { @Input() size: number | string; // 想要用双向绑定语法,output变量名就一定是输入属性名加上Change @Output() sizeChange = new EventEmitter<number>(); constructor() { } ngOnInit(): void { } dec() { this.resize(-1); } inc() { this.resize(+1); } resize(delta: number) { this.size = Math.min(40, Math.max(8, +this.size + delta)); this.sizeChange.emit(this.size); } }
父组件
import { Component } from '@angular/core';@Component({ selector: 'app-root', template: ` <app-sizer [(size)]="fontSizePx"></app-sizer> <div [style.font-size.px]="fontSizePx">Resizable Text</div> `, })export class AppComponent { fontSizePx = 16; }
双向绑定工作原理
为了使双向数据绑定有效,@Output() 属性的名字必须遵循 inputChange 模式,其中 input 是相应 @Input() 属性的名字。例如,如果 @Input() 属性为 size ,则 @Output() 属性必须为 sizeChange 。
上面的 sizerComponent 具有值属性 size 和事件属性 sizeChange。 size 属性是 @Input(),因此数据可以流入 sizerComponent 。 sizeChange 事件是一个 @Output() ,它允许数据从 sizerComponent 流出到父组件。
上面例子,有两个方法, dec() 用于减小字体大小, inc() 用于增大字体大小。这两种方法使用 resize() 在最小/最大值的约束内更改 size 属性的值,并发出带有新 size 值的事件。
简写形式
双向绑定语法是属性绑定和事件绑定的组合的简写形式
<app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer>
表单中的双向绑定
因为没有任何原生 HTML 元素遵循了 x 值和 xChange 事件的命名模式,所以与表单元素进行双向绑定需要使用 NgModel
基本使用
根据之前基本的双向绑定知识,[(ngModel)]语法可拆解为:
- 名为ngModel的输入属性
- 名为ngModelChange的输出属性
使用[(ngModule)]双向绑定的前提条件是在模块中引入FormsModule
import {Component} from '@angular/core'; @Component({ selector: 'example-app', template: ` <input [(ngModel)]="name" #ctrl="ngModel" required> <p>Value: {{ name }}</p> <p>Valid: {{ ctrl.valid }}</p> <button (click)="setValue()">Set value</button> `, }) export class SimpleNgModelComp { name: string = ''; setValue() { this.name = 'Nancy'; } }
<input [(ngModel)]="name" /> 上面这行代码相当于: <input [value]="name" (input)="name = $event.target.value" />
在表单中的使用
表单中使用[(ngModel)],需要做下面两件事的其中之一
- 给控件加上name属性
- 将ngModelOptions.standalone设为true
<form> <input [(ngModel)]="value" name="name" /> <input [(ngModel)]="value" [ngModelOptions]="{ standalone: true }" /> </form>
注意:表单中使用双向数据绑定,知识点比较多,这里只做简单了解,后续会出专门章节探讨
内置指令
循环指令 *ngFor (非常基础,掌握)
arr:string[] = ['张三','李四','王五']; trackByItems(index: number, item: Item): number { return item.id; } <div *ngFor="let item of arr; let i=index" (click)='choseThis(item,i)'> 索引值:{{i}} -- 内容:{{item}} </div> //trackBy一般和长列表一起使用,减少dom替换次数,提升性能 <div *ngFor="let item of items; trackBy: trackByItems"> ({{item.id}}) {{item.name}} </div>
条件渲染 *ngIf ngStyle ngClass ngSwitch(非常基础)
isShow: Boolean = true; personState: number = 2; //频繁切换不建议用,频繁加载和移除有较高的性能消耗 (重要) <p *ngIf="isShow">命令模式</p> // 不频繁切换推荐用 <p [hidden]="isShow">命令模式</p> // 频繁切换推荐用 currentStyles = { 'font-style': this.canSave ? 'italic' : 'normal', 'font-weight': !this.isUnchanged ? 'bold' : 'normal', 'font-size': this.isSpecial ? '24px' : '12px' }; <div [ngClass]="isSpecial ? 'special' : ''">ngClass</div> <div [ngStyle]="currentStyles"> ngStyle </div> // 使用样式有2种(style.dispaly 和 class.hidden) <p [style.display]="isShow?'block':'none'">style模式</p> //频繁切换建议用样式 <p [class.hidden]="isShow">class模式</p> //匹配多种情况的条件渲染,跟vue的v-if/v-else-if/v-else类似 //适合多种状态,显示一种的情况 <div [ngSwitch] = 'personState'> <div *ngSwitchCase="1">工作</div> <div *ngSwitchCase="2">吃饭</div> <div *ngSwitchDefault>睡觉</div> </div>
双向数据绑定指令 [(ngModel)]
//Angular不能直接识别ngModel,需要通过引入模块FormsModule来访问 import {FormsModule} from '@angular/forms'; imports: [FormsModule] public name = "张三"; <input [(ngModel)] = "name" type="text"> //人工绑定,更好的做法是通过响应式表单绑定 <input bindon-change="name" type="text"> //备选 //属性绑定+事件绑定 = ngModel (重要) <input [value]="name" (input)="name=$event.target.value" >
模板引用变量
基本使用
使用井号(#)声明模板引用变量,可以获取DOM 元素、指令、组件、TemplateRef 或 Web Component。
import {Component} from '@angular/core'; @Component({ selector: 'app-tpl-var', template: ` <input #phone placeholder="phone number" /> <button (click)="callPhone(phone.value)">Call</button> `, }) export class TplVarComponent { constructor() { } callPhone(value: string) { console.log('callPhone', value); } }
ref
还有种写法就是ref, 下面两种写法是一样的
<input #fax placeholder="fax number" /> <input ref-fax placeholder="fax number" />
引用组件
在组件章节,介绍了获取子组件的属性和方法,有两种方法:本地变量和@viewChild()
import {Component} from '@angular/core'; @Component({ selector: 'app-tpl-var', template: ` <div class="demo-sec"> <button class="btn btn-primary" (click)="sizer.inc()">app inc</button> <app-sizer [(size)]="size" #sizer></app-sizer> size: {{ size }} </div> `, }) export class TplVarComponent { size = 16; constructor() { } }
输入和输出
输入属性
子组件
import { Component, Input } from '@angular/core'; @Component({ selector: 'app-root', template: `<p> Today's item: {{item}} </p>` }) export class ItemDetailComponent { @Input() item: string; }
父组件
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <app-item-detail [item]="currentItem"></app-item-detail> `, }) export class AppComponent { currentItem = 'Television'; }
输出属性
子组件
import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-root', template: `<label>Add an item: <input #newItem></label> <button (click)="addNewItem(newItem.value)">Add to parent's list</button>`, }) export class ItemOutputComponent { @Output() newItemEvent = new EventEmitter<string>(); addNewItem(value: string) { this.newItemEvent.emit(value); } }
父组件
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <app-item-output (newItemEvent)="addItem($event)"></app-item-output> `, }) export class AppComponent { items = ['item1', 'item2', 'item3', 'item4']; addItem(newItem: string) { this.items.push(newItem); } }
在元数据中声明输入和输出属性
固然可以在 @Directive 和 @Component 元数据中声明 inputs 和 outputs, 不推荐提供别名。
@Input()和@Output()可以接收一个参数,作为变量的别名,那么父组件中只能用别名绑定 子组件
import { Component, Input, EventEmitter, Output } from '@angular/core'; @Component({ selector: 'app-root', template: `<p> Today's item: {{item}} </p>` }) export class ItemDetailComponent { @Input('aliasItem') item: string; // decorate the property with @Input() @Output('newItem') newItemEvent = new EventEmitter<string>(); addNewItem(value: string) { this.newItemEvent.emit(value); } }
父组件
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <app-item-detail [aliasItem]="currentItem" (newItem)="addItem($event)"></app-item-detail> `, }) export class AppComponent { currentItem = 'Television'; items = ['item1', 'item2', 'item3', 'item4']; addItem(newItem: string) { this.items.push(newItem); } }
输入属性一定要用中括号[]绑定?
如果绑定的值是静态的,就不需要[]
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <app-item-detail item="static item"></app-item-detail> `, }) export class AppComponent { // currentItem = 'Television'; }
管道(基础,掌握)
常用的管道
1、大小写字母转换
str = 'Hello'; str1 = 'World'; <p>{{str | uppercase}}-{{str1 | lowercase}} </p> //str:hello str1:WORLD
2、 日期格式化(经常使用)
today = new Date(); <p>现在的时间是{{today | date:'yyyy-MM-dd HH:mm:ss'}}</p>
3、保留小数后面多少位 下面例子的含义是,3表示最少几位整数,后面的2-4表示最少最少2位小数,最多4位小数,不足补零,小数会四舍五入。
num = 125.156896; <p>num保留4位小数的值是:{{num | number:'3.2-4'}}</p> //125.1569
4、货币转换
count = 5; price = 1.5; <p>数量:{{count}}</p> // 数据:5 <p>价格:{{price}}</p> // 价格:1.5 <p>总价:{{(price * count) | currency:'¥'}}</p> // 价格:¥7.5
5、字符串截取
name = '只对你说'; <p>{{name | slice : 2 : 4}}</p> // 你说
6、json格式化(有时需要看一下数据)
<p>{{ { name: 'semlinker' } | json }}</p> // { "name": "semlinker" }
自定义管道
1、创建管道文件
ng g pipe /piper/mypiper
2、在管道文件中写自己的逻辑transform两个参数分别表示传入值和参数
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'multiple' }) export class MypiperPipe implements PipeTransform { transform(value: any, args?: any): any { //value:输入值 args:参数 if(!args){//无参的情况下 args = 1; } return value*args; } }
注意:通过命令行生成的管道(过滤器),会自动在全局声明; 管道传入的参数是在':'冒号后面表示
更多编程相关知识,请访问:编程视频!!
위 내용은 Angle10에서 템플릿에 데이터 바인딩을 수행하는 방법에 대해 이야기해 볼까요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.

이 기사에서는 Contrim에 의해 확보 된 백엔드와의 프론트 엔드 통합을 보여 주며 Next.js를 사용하여 기능적인 Edtech SaaS 응용 프로그램을 구축합니다. Frontend는 UI 가시성을 제어하기 위해 사용자 권한을 가져오고 API가 역할 기반을 준수하도록합니다.

JavaScript는 현대 웹 개발의 핵심 언어이며 다양성과 유연성에 널리 사용됩니다. 1) 프론트 엔드 개발 : DOM 운영 및 최신 프레임 워크 (예 : React, Vue.js, Angular)를 통해 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축합니다. 2) 서버 측 개발 : Node.js는 비 차단 I/O 모델을 사용하여 높은 동시성 및 실시간 응용 프로그램을 처리합니다. 3) 모바일 및 데스크탑 애플리케이션 개발 : 크로스 플랫폼 개발은 개발 효율을 향상시키기 위해 반응 및 전자를 통해 실현됩니다.

JavaScript의 최신 트렌드에는 Typescript의 Rise, 현대 프레임 워크 및 라이브러리의 인기 및 WebAssembly의 적용이 포함됩니다. 향후 전망은보다 강력한 유형 시스템, 서버 측 JavaScript 개발, 인공 지능 및 기계 학습의 확장, IoT 및 Edge 컴퓨팅의 잠재력을 포함합니다.

JavaScript는 현대 웹 개발의 초석이며 주요 기능에는 이벤트 중심 프로그래밍, 동적 컨텐츠 생성 및 비동기 프로그래밍이 포함됩니다. 1) 이벤트 중심 프로그래밍을 사용하면 사용자 작업에 따라 웹 페이지가 동적으로 변경 될 수 있습니다. 2) 동적 컨텐츠 생성을 사용하면 조건에 따라 페이지 컨텐츠를 조정할 수 있습니다. 3) 비동기 프로그래밍은 사용자 인터페이스가 차단되지 않도록합니다. JavaScript는 웹 상호 작용, 단일 페이지 응용 프로그램 및 서버 측 개발에 널리 사용되며 사용자 경험 및 크로스 플랫폼 개발의 유연성을 크게 향상시킵니다.

Python은 데이터 과학 및 기계 학습에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 간결한 구문 및 풍부한 라이브러리 생태계로 유명하며 데이터 분석 및 웹 개발에 적합합니다. 2. JavaScript는 프론트 엔드 개발의 핵심입니다. Node.js는 서버 측 프로그래밍을 지원하며 풀 스택 개발에 적합합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

Dreamweaver Mac版
시각적 웹 개발 도구

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기

PhpStorm 맥 버전
최신(2018.2.1) 전문 PHP 통합 개발 도구
