angular img 404的問題
必須放在src/assets
請使用相對路徑
Form 查找后台的
以前
fg.controls['name']
fg.controls['address'].controls['city']
現在
fg.get('address.city')
fg.get(['address', 'street'])
禁用
fg.controls['name'].disable();
fg.controls['city'].disable({ onlySelf: true }); // 不更新父級
解除 enabled
Form 輸入字母轉大寫
NgModel
<input type="text" [(ngModel)]="num" appMyDirective>
import {Directive, HostListener} from '@angular/core';
import {NgModel} from '@angular/forms';
@Directive({
selector: '[appMyDirective]'
})
export class MyDirectiveDirective {
constructor(private model: NgModel) {
}
@HostListener('input', ['$event.target'])
ngModelChanges(e) {
let a=e.value.toUpperCase()
// 寫入
this.model.valueAccessor.writeValue(a)
// 更新
this.model.viewToModelUpdate(a)
}
}
formControlName
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<label>
firstName: <input type="text" formControlName="firstName">
</label>
<label>
lastName: <input type="text" formControlName="lastName">
</label>
<div formGroupName="address">
<label>
address1: <input type="text" formControlName="address1">
</label>
<label>
address2: <input type="text" formControlName="address2" >
</label>
</div>
</form>
public myForm: FormGroup;
public str:string;
constructor( private fb: FormBuilder) {
this.myForm = this.fb.group({
firstName: [''],
lastName: [''],
address: this.fb.group({
address1: [''],
address2: [''],
})
});
this.myForm.valueChanges.subscribe(e => {
if(this.str!==this.myForm.get('firstName').value){
this.myForm.get('firstName').setValue(e.firstName.toUpperCase(),{onlySelf:true})
}
this.str=this.myForm.get('firstName').value;
});
}
升級版本
<label>
address2: <input type="text" formControlName="address2" appMyDirective>
</label>
export class MyDirectiveDirective {
constructor(private injector: Injector) { }
@HostListener('input', ['$event.target'])
ngModelChanges(e) {
let a = e.value.toUpperCase();
// 這個代碼好牛逼,拿到注射器實例
let {control} = this.injector.get(NgControl);
control.setValue(a)
// 更新規則
control.updateValueAndValidity();
}
}
注冊器的相關使用
新建一個服務
import {Injectable} from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class HelloService {
constructor() {
}
say(from: string) {
console.log(`hello ${from}`);
return true;
}
}
組件中直接查找使用
ngAfterViewInit() {
const service=inject(HelloService)
service.say('AppModule')
}
服務的使用
useClass
告訴我們使用了那個類
import {Injectable} from '@angular/core';
@Injectable({
providedIn: 'root',
useClass:HelloService
})
export class HelloService {
constructor() {
}
say(from: string) {
console.log(`hello ${from}`);
return true;
}
}
進行使用
constructor(private helloService:HelloService) {
this.helloService.say('bbbb')
}
創建庫
ng g library my-lib
在projects
里面有個 my-lib
項目文件夾
在package.json
"ng-packagr": "^10.0.0",
app.module
import {MyLibModule} from '../../projects/my-lib/src/lib/my-lib.module'
@NgModule({
imports: [
MyLibModule
]
})
頁面的使用
<lib-my-lib></lib-my-lib>
主模塊子模塊關於NavigationEnd 問題
同事今天遇到一個問題主模塊
app.component
的Router.event
事件無法檢測某個模塊的NavigationEnd
事件最終通過跟同事一起分析的解決思路是
主模塊應該把 router.event 放在 constructor 而子模塊的東西應該放在生命周期里面`ngOnInit`
發現一個有趣的問題
如果判斷click
和drag
事件
let a=document.querySelector('#aaa');
merge(
fromEvent(a,'mousedown').pipe(mapTo(1)),
fromEvent(a,'mousemove').pipe(mapTo(2)),
).pipe(
sample(fromEvent(a,'mouseup'))// 促發條件:松開鼠標促發
).subscribe(flag=>{
if (flag == 1) {
console.log('click');
}else if (flag == 2) {
console.log('drag');
}
})
雙向數據綁定css變量
<input type="number" [(ngModel)]="x">
<p [style.--num]="x">hello world</p>
p{
font-size:calc(var(--num)*1px)
}
x = 20;
我們發現 x=20
變量了css變量進行操作
自定義指令
<div appChColor>
hello world
</div>
@Directive({
selector: '[appChColor]'
})
export class ChColorDirective {
constructor(
private el: ElementRef,
private renderer: Renderer2
) {
this.changeColor('red')
}
changeColor(color: string) {
this.renderer.setStyle(this.el.nativeElement, 'color', color)
}
// click 的時候修改顏色
@HostListener('click')
foo(){
this.changeColor('green')
}
}
Rxjs 錯誤處理
this.http.get('/assets/data.json--').pipe(
catchError(error=>of([]))
).subscribe(res=>{
console.log(res);
})
- 我們正在向catchError運算符傳遞一個函數,這是錯誤處理函數
- 錯誤處理函數不會立即被調用,通常,通常不會被調用
type TypeArrays = {
data: Array<any>
}
export class UserComponent implements OnInit {
constructor() {}
loading: boolean;
arr: Array<any>
ngOnInit(): void {
this.http.get<TypeArrays>('/assets/data.json').pipe(
finalize(() => {
this.loading = !!this.arr.length;
})
).subscribe(res => {
this.arr = res.data;
})
}
}
angular 不變形的重要性
<app-dev-card-v1 class="card" *ngFor="let dev of devs" [dev]="dev">
</app-dev-card-v1>
ngOnChanges生命周期檢測值發生變化
set 輸入屬性,ngOnChanges生命周期掛鈎的替代方法,並在傳遞新值時執行
@Input()
set dev(val: Dev) {
this._dev = val;
this.seniorityLevel = this.getSeniorityLevel();
}
如果您不能輕松地切換到不變的更新模式,則解決陳舊數據呈現問題的一種方法是使用getter即時計算視圖模型數據
export class DevCardV5Component {
@Input() public dev: Dev;
public get seniorityLevel(): SeniorityLevel {
console.log("seniorityLevel getter called");
return this.getSeniorityLevel();
}
private get skill(): number {
return this.dev.skill;
}
}
但是,您仍然不能使用該組件的OnPush更改檢測策略。而且,在每個更改檢測周期都將調用getter
另一種選擇是在ngDoCheck生命周期掛鈎中執行計算,它被認為是不得已的方法,因為與getter相似,它在每個變更檢測周期內都會被調用
ngDoCheck() {
this.seniorityLevel = this.getSeniorityLevel();
}