zoukankan      html  css  js  c++  java
  • Angular : 响应式编程, 组件间通信, 表单

    Angular 响应式编程相关

    -------------------------------------------------------------------------------------------------

    rxjs6 中需要导入 import 'rxjs/Rx'

    创建一个流并观察(订阅)它:

    Observable.from([1,2,3,4]).filter(e => e%2 == 0).map(e => e*e).subscribe(e => console.log(e), err => console.error(err), () => console.log('结束'));

    ----------------------------以上写法不推荐---------------------------------------------

    rxjs6版本, 可以直接使用 from() 来创建一个流, 所有filter, map等操作要写在 pipe()函数里面当做参数.

    --------------------------------------------------------------------------------------------------------------------

    Observable是一个流, subscribe监听一个流(订阅)它是一个观察者

    模板本地变量 : <input #myField (keyup)="onKey(myField.value)"> 这样可以直接用string类型接收myField.value的值
    用#xxx来声明一个变量,使用变量时不需要加#

    angular的forms模块中有一个ReactiveFormsModule做响应式编程的模块,有一个对象FormControl可以用它来进行响应式表单验证

    模板里面用 [formControl]="titleFilter" 把input和控制器里面的titleFilter绑在一起

    private titleFilter: FormControl = new FormControl();

    constructor(private productService: ProductService) {
    this.titleFilter.valueChanges
    .subscribe(
    value => {xxxxxxxx;}
    );
    }

    上面的例子是订阅它的valueChanges 事件流

    Angular 组件间通信相关

    -------------------------------------------------------------------------------------------------

    父子组件间传递数据 子组件用@Input装饰的变量接收,父组件用 [xxx]=yyy的方式在子组件标签内传值,子组件数据的变化不会影响父组件

    组件往父组件发射数据用 EventEmitter 可以这样写:

    @Output('这里面可以写事件名字')
    aObj: EventEmitter<Obj> = new EventEmitter;

    aObj.emit(aObj)

    EventEmitter<Obj> 表示往外发射的数据类型是一个Obj类型,那么用emit方法发射数据的aObj必须是一个Obj类型

    捕获发射的数据需要用 (事件名字)="xxxxHandler($event)" 控制器里面用 xxxxHandler(event: Obj) 来接收这个event就是发射出来的Obj类型的数据, 如果@Output发射的EventEmitter对象名字(aObj)是xxxChange,并且@Input的名字也是xxx,那么可以直接在父组件中用[(xxx)]="yyy"这种语法双向绑定.

    -----------------------------------------------------------------------------------------------------

    中间人是两个组件共同的父组件,可以先捕获一个组件发射出来的数据 (事件名字)="xxxxHandler($event)" 然后在传给另一个子组件 [xxxxx]="xxxxxx"

    -----------------------------------------------------------------------------------------------------

    在父组件控制器中调用子组件的方法. 首先在父组件模板中 <app-child #child1></app-child> 给子组件声明一个模板本地变量

    然后在控制器中用下面这个装饰器来声明一个ChildComponent类型的对象. 然后可以用 child1.xxx() 来调用子组件的方法.

    @viewChild("child1")
    child1: ChildComponent;

    也可以直接在父组件的模板中用 (click)="child1.xxx()" 的方式来调用子组件的方法. 这两种方式都需要声明子组件的模板本地变量(尽量避免使用@viewChild这种方式调用方法,因为这会造成紧耦合)

    -----------------------------------------------------------------------------------------------------

    投影:可以把父组件的html投影到子组件中去,首先在子组件模板中用<ng-content></ng-content>标记一个投影点,然后在父组件中用 <app-child>要投影到子组件中的html<app-child>, 还可以有多个投影.如父组件模板中给需要投影的html一个类,那么子组件就用 <ng-content select=".xxx类名"></ng-content> 的方式来表名要把那一段代码投影到这上面.

    Angular 表单相关

    -------------------------------------------------------------------------------------------------

    如果是模板表单,需要引入 FormsModule 如果是响应式表单需要引入 ReactiveFormsModule

    angular会在所有表单上自动添加 ngForm 指令 ,会隐式创建一个 FormGroup类的实例,如果不想让angular接管表单,需要在表单上添加 ngNoForm . ngForm指令也可以添加到div上.移除html默认验证用 novalidate

    ngForm 会扫描所有 标有 ngModel的子元素并将他们的值添加到表单数据模型中.

    ngmodel在表单里面不用加 [()] 直接写一个 ngModel 就可以 ,他会隐式创建一个FormControl类的实例

    可以用模板本地变量的方式给一个表单声明:#myForm="ngForm" 然后用 (ngSubmit)="onSubmit(myForm.value)" 这种方式指定提交的函数.以及把form里面 ngmodel元素的值传给函数

    ngModelGroup 可以把一部分表单字段组成一个组,嵌套在表单里面,形成一个元素,也会隐式创建一个FormGroup的类的实例.<div ngModelGroup="useInfo">嵌套的表单元素</div>

    ----------------------------------------------------------------------------------------------------------

    响应式表单 的三个类 : FormControl 可以理解为一个表单元素, FormGroup 多个FormControl的对象的形式(key, value)
    FormArray 多个FormControl 的数组的形式. 提交用(submit)="onSubmit()"

    响应式表单的指令: 如下图

    (其中 formGroup和formControl指令不能嵌套存在, formGroup可以用在表单上, formControl适合绑定单独的input框, 在formGroup里面只能也必须使用带name的三个指令, 三个带name的指令不能用数据绑定的方式绑定)

    构建数据模型的时候可以直接用 FormBuilder 需要在构造函数中注入进去 constructor(fb: FormBuilder) 简单例子:

    constructor(private fb: FormBuilder) {
    this.formModel = fb.group({
    username: [''],
    mobile: [''],
    passwordsGroup: fb.group({
    password: [''],
    pconfirm: ['']
    })
    });
    }

    其中每个字段的[''](不一定加单引号,这里是因为都是字符串)里面都可以有三个字段,第一个是默认值,第二个是校验器,第三个是异步的校验器,angular预定义好的校验器是 Validators 这个类里面的静态方法.如 username: username: ['', [Validators.required, Validators.minLength(6)]],
    可以用 let isValid: boolean = this.formModel.get('username').valid; 这种方式取出是否符合校验规则的值.符合为true
    还可以用 let errors: any = this.formModel.get('username').errors; 这种方式取出校验错误信息.

    自定义校验器的demo: 只有formModel里面所有字段都符合校验器,那么 formModel.valid才为true.
    注意:自定义校验器如果通过的话,一定要返回 null.

    ------------------------------------------------------------------------------------------------------

    mobileValidator(control: FormControl): any {
    var myreg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+d{8})$/;
    let valid = myreg.test(control.value);
    console.log("校验结果"+valid);
    return valid ? null : {mobile: true};
    }

    equalValidator(group: FormGroup): any {
    let password: FormControl = group.get('password') as FormControl;
    let pconfirm: FormControl = group.get('pconfirm') as FormControl;
    let valid: boolean = (password.value === pconfirm.value);
    console.log('密码是否相等'+valid);
    return valid ? null : {equal: true};
    }

    formModel: FormGroup;

    constructor(private fb: FormBuilder) {
    this.formModel = fb.group({
    username: ['', [Validators.required, Validators.minLength(6)]],
    mobile: ['', this.mobileValidator],
    passwordsGroup: fb.group({
    password: [''],
    pconfirm: ['']
    }, {validator: this.equalValidator})
    });
    }

    ------------------------------------------------------------------------------------------------------

    注意,  判断校验是否正确 在模板中, 一种是  formModel.get('username').hasError('required') 还有就是 formModel.hashError('required', 'username')

  • 相关阅读:
    水晶苍蝇拍:从“航空母舰”看企业竞争优势分析 (2010-05-11 11:48:38)
    水晶苍蝇拍:为何设定了安全边际后还吃大跌?
    水晶苍蝇拍:“低风险,高不确定性”的启示 (2010-04-24 22:02:13)
    水晶苍蝇拍:我这样看投资的安全性 (2009-08-27 20:08:53)
    水晶苍蝇拍:不同企业的估值差告诉我们什么? (2010-04-21 20:56:19)
    水晶苍蝇拍:估值,像雾像雨又像风 (2010-03-15 10:44:16)
    水晶苍蝇拍:长持的简单逻辑 (2009-05-25 18:08:43)
    Android中RelativeLayout各个属性的含义
    有道词典 Andriod 版本数据格式分析
    电驴提示“该内容尚未提供权利证明,无法提供下载”之解决办法详解
  • 原文地址:https://www.cnblogs.com/cccy0/p/9544437.html
Copyright © 2011-2022 走看看