https://www.youtube.com/watch?v=ielZaY4a_Jc&list=PL9LUW6O9WZqgUMHwDsKQf3prtqVvjGZ6S&index=11
S06由Kevin Yang大大主講,藉由大大導讀文件後,我們就有能力能自己查文件了
因為Kevin Yang大大的內容蠻多的,所以還是依照讀書會分2天來寫
ng new s06e02 # 我是選要routing,scss
建完後先看src/目錄
index.html裡的,是定義在app/app.component.ts的selector裡
一個angular專案至少會有一個component在最上層(俗稱root component)
此root component會註冊在app.module.ts的
@NgModule({ # @NgModule是裝飾子(decorator),用來結構性描述此class的metadata
declarations: [
AppComponent # 宣告
],
imports: [
BrowserModule,
AppRoutingModule
],
providers: [],
bootstrap: [AppComponent] # 起始的component
})
來看一下app.component.ts裡頭的@Component
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'] # 這是陣列,可以指到多份style sheet
})
https://angular.io/api?type=decorator
https://angular.io/api/core/Component
可以看到所有的選項(Option),介紹比較重要的
https://angular.io/api/core/Component#inherited-from-directive-decorator
所以適用一堆Directive decoratord的Option,來看一下@Directive的Option
以下已不建議使用在@Component裡面,建議寫在export class MyAppComponent {...}
3個基本功
{{ varName }}
{{ varName + '!!' }} /*可以串簡單的東西*/
假設name='Angular!!'
<input type="text" [value]="name" /> /*property*/
<input type="text" [attr.id]="name" /> /*attribute,attribute的名稱為id*/
最後結果會類似 <input _ngcontent-c37 type="text" id="Angular!!")>
1.html
<button (click)="show()">show alert</button>
2.ts
show(){ alert(''); }
事件回傳的$event有很多種,常用的property有target
若不知道是哪種event,可以console.log出來,再到MDN查看
例如:MouseEvent,在MDN右上角Search「MouseEvent」,可查相關properties
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
<button (click)="getEvent($event)">xxx</button>
getEvent(v){
console.log(v); // 用mouse點,傳進來的是MouseEvent
console.dir(v);
}
// $event.target = button // event的target,事件作用的對象
<input type="text" [(ngModel)]="name" /> /*值會與ts裡的name變數同步*/
可拆開寫成
<input type="text" [ngModel]="name" (ngModelChange)="name=$event" />
property binding event binding ^^^^^^故定寫法
拆開寫的使用情境:不止單純同步變數,還想要額外做一些事情
<input type="text" [ngModel]="name" (ngModelChange)="doSomething($event)" />
doSometing(value){
console.log(value); // 多做一些事情
this.name=value;
}
https://itw01.com/G2YWE3X.htmlhttps://itw01.com/G2YWE3X.html
參考文章:https://itw01.com/G2YWE3X.html
假設有個html內容為
<input id="test" class="blue" type="radio" custom-attr="1" />
// javascript語法
document.getElementById('test').id; // 取得id
document.getElementById('test').className = 'red'; // 設定class,因為js裡頭class是關鍵字,要用className來取得css的class
document.getElementById('test').checked; // get radio button's status
document.getElementById('test').checked = true; // set radio button's status
// 還能設定物件
$('#test').prop('foo', { age: 23, name: 'John' }); // 使用jquery設定一個名為foo的物件 document.getElementById('test').foo.age; // return number型別: 23 document.getElementById('test').foo.name; // return string型別: "John"
// jQuery語法
$('#test').prop('checked'); // boolean
$('#test').prop('checked', true);
var input = document.getElementById('search');
input.value = 'foo2';
input.getAttribute('value'); // return string: "foo"
document.getElementById('test').getAttribute('custom-attr') // javascript的取法
$('#test').attr('custom-attr') // jQuery的取法
1.ts
items = [1,2,3]; // Iterable
2.html
<ul>
<li *ngFore="let item of items"> {{ item }} </li>
</ul>
1.ts
show = false;
2.html
<button (click)="show = !show">toggle show</button>
<span *ngIf="show">show</span>
<div [ngSwitch]="someItem.type">
<classA-item *ngSwitchCase="'A'" [item]="someItem"> </classA-item>
<classB-item *ngSwitchCase="'B'" [item]="someItem"> </classB-item>
都沒符合的時候
<classOther-item *ngSwitchDefault [item]="someItem"> </classOther-item>
</div>
不能寫成
<div *ngFor="let item of items" *ngIf="items.legth > 2">
要寫多層
<div *ngFor=...>
<div *ngIf=...>xxx</div>
</div>
語法: #變數
此變數可以直接在html上定義,不一定要在ts裡面宣告
同一個scope裡,變數名稱不能重複。但在*ngFor裡不在此限(屬於同個scope,會包在裡)
1.html
<div #content>some text</div>
<input type="text" #v1 (keyup.enter)="showValue(v1)" />
也可以傳其他的template reference
<input type="text" #v2 (keyup.enter)="showValue(content)" />
2.ts
showValue(input: HTMLInputElement){
console.log(input); // 傳入該input的本體
}
showValue(input: HTMLDivElement){
input.innerHTML = 'change text'; // 把some text改成change text
}
HTMLInputElement
https://developer.mozilla.org/zh-TW/docs/Web/API/HTMLInputElement
有很多property可用
ng-template使用情境
設定好一個要顯示的內容,當符合條件時才顯示(例如:錯誤訊息、提示訊息)
<span *ngIf="show; else showNothing">
show
</span>
<ng-template #showNothing>
nothing to show
</ng-template>
建個可重複使用的component
ng g c hello
1.hello.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'hello',
template: `
<h1>Hello {{ name }} </h1>
<button (click)="doSend()">output demo</button>
`,
styleUrls: ['./hello.component.scss']
})
export class HelloComponent {
@Input() nameB: string; // 外部傳進來
@Output() send: EventEmitter<any> = new EventEmitter();
doSend() {
// EventEmitter 傳值的方式
this.send.emit('from hello component'); // 會放在 $event
}
}
2、在app.component.html使用
<hello [nameB]="name" (send)="getEvent($event)"></hello>
^^^^^^^^^^^^^^^
/*
把app.component.ts的name丟進hello當@Input
用 (send)="getEvent($event) 來接 hello丟出來的Output,'from hello component'放在$event裡面
[name] 要對應 @Input() name
(send) 要對應 @Output() send
不過可以用「別名」改寫成
@Input('name') nameLongLongLong: string; // 'name'是對外,內部是使用nameLongLongLong
*/
import { Component, HostBinding, HostListener } from '@angular/core';
@Component({
selector: 'hello',
template: `
<h1>Hello {{ name }} </h1>
<button (click)="doSend()">output demo</button>
`,
styleUrls: ['./hello.component.scss']
})
export class HelloComponent {
// 針對此component的property做binding
@HostBinding('style.color') fontColor = 'red';
// 針對此component的event做listener(監聽)
@HostListener('click', ['$event']) // 當在appComponent對hello做click時觸發
whenClick(event) {
console.log(event);
}
doSend() {
this.fontColor = 'pink';
}
}