zoukankan      html  css  js  c++  java
  • angular11学习(十八)

    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.componentRouter.event 事件无法检测某个模块的NavigationEnd 事件

    最终通过跟同事一起分析的解决思路是

    主模块应该把 router.event 放在 constructor 
    而子模块的东西应该放在生命周期里面`ngOnInit`
    

    发现一个有趣的问题

    如果判断clickdrag 事件

     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();
      }
    
  • 相关阅读:
    Node Sass could not find a binding for your current environment : Node.js 8.x -SpiritMark
    SpringBoot从入门到精通教程(八)
    注解 @CrossOrigin
    出现VMware Workstation 无法连接到虚拟机。请确保您有权运行该程序、访问该程序使用的所有目录以及访问所有临时文件目录。 未能将管道连接到虚拟机: 所有的管道范例都在使用中。
    说一下 JSP 的 4 种作用域?
    jsp有哪些内置对象?作用分别是什么?
    MVC的各个部分都有那些技术来实现?如何实现?
    你所了解的的软件测试类型都有哪些,简单介绍一下。
    你的测试职业发展目标是什么?
    您认为做好测试用例设计工作的关键是什么?
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/14136564.html
Copyright © 2011-2022 走看看