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();
}