6.ng-zorro传值

322 阅读2分钟

传值方式

常用传值方式有:

存储:先存后取,不能同步更新

即时传递:值变动时,同步更新

一次性传递:仅使用一次,不再更新

存储

存储方式有多种,常用的:

本地存储:localStorage、sessionStorage

localStorage.getItem(key);
localStorage.setItem(key,value);
sessionStorage.getItem(key);
sessionStorage.setItem(key,value);

服务存储

import { Injectable } from '@angular/core';

@Injectable()
export class DataService {
  private data: string;

  getData(): string {
    return this.data;
  }

  setData(value: string): void {
    this.data = value;
  }
}

一次性传递

仅使用一次即可,多用于浏览器url拼接参数。

http://xxx?data=1

即时传递

值变动时,同步更新,传值要避免传Object类型的值,防止值被共用导致问题。(Object传递的是引用路径)

1.组件关系--父向子传值

通过@input实现父向子的传值

父组件
<div class="app-item">
    <app-item-detail [item]="currentItem"></app-item-detail>
</div>
子组件
ngOnChanges(changes: SimpleChanges) {
  for (const propName in changes) {
    const chng = changes[propName];
    // 获取值后调用对应方法
  }
}

也可以通过在父组件中获取子组件模块去达到传值效果

父组件html
<div class="app-item">
    <app-item-detail #appItemDetail></app-item-detail>
</div>
父组件ts
// 在父元素中获取子元素组件
@ViewChild('appItemDetail') appItemDetail: AppItemDetailConponent;
// 可以直接调用子元素的方法
this.appItemDetail.forchange(data)
2.组件关系--子向父传值

子向父元素传值大多用的都是@output方法

父组件html
<div class="app-item">
    <app-item-detail (itemEvent)="addItem($event)"></app-item-detail>
</div>
子组件ts
// 在子元素组件定义标签上名称一样的event
@Output() itemEvent = new EventEmitter();
// 通过emit可以将值传递给父元素
this.itemEvent.emit(value);
3.组件关系--共同父元素

也是通过子组件传给父组件,然后父组件调用子组件的方法。

父元素html
<div class="app-item">
    <app-item-detail #appItemDetail></app-item-detail>
    <app-item-detail2 (itemEvent)="addItem($event)"></app-item-detail2>
</div>
父元素ts
// 在父元素中获取子元素组件
@ViewChild('appItemDetail') appItemDetail: AppItemDetailConponent;
// 获取另一子组件@output传值
addItem(event) {
    // 调用子元素的方法
    this.appItemDetail.forchange(data)
}
3.组件关系--同在app中,毫无关系

例如头部有新消息提醒,在某个tab中点击确认后,头部消息也要置为已读。(只是场景,抛开websocket推送)

使用的是@Input和@Output的底层方法:Observables的subject方法。

MessageService服务
import {Injectable} from '@angular/core';
import {Subject} from 'rxjs';

@Injectable()
export class MessageService {
    private user = new Subject();
    user$ = this.user.asObservable();
    
    changeUser(data) {
        this.user.next(data);
    }
}
传递消息的模块
// 引入服务
constructor(private msgService:MessageService)
// 调用传递消息的方法
this.msgService.changeUser('123');
接受消息的模块
// 引入服务
constructor(private msgService:MessageService)
// 获取传递的消息
this.msgService.user$.subscribe((data) => {
  console.log(data);
})

优化写法:多次使用时,要在服务中定义多个变量,会导致服务臃肿。

export class MessageService {
    private user = new Subject();
    user$ = this.user.asObservable();
    
    private permission = new Subject();
    permission$ = this.permission.asObservable();
    
    changeUser(data) {
        this.user.next(data);
    }
    
    changePermission(data) {
        this.permission.next(data);
    }
}

优化写法:将所有使用变量存储到Map对象中

MessageService服务
import { Injectable } from '@angular/core';
import { Subject, Subscription } from 'rxjs';

@Injectable()
export class MessageService {
    // 定义map接受需要变动的字段
    private messageObservables = new Map<string, any>();
    // 根据字段发送消息
    Send(moduleId: string, message: any) {
        this.getMessageObservable(moduleId).next(message);
    }
    // 定义字段并提供处理接受消息的方法
    On(moduleId: string, observerOrNext?: any): Subscription {
        return this.getMessageObservable(moduleId).subscribe(observerOrNext);
    }
    // 获取字段,从Map中获取,没有就创建
    getMessageObservable(moduleId: string) {
        let messageObservable = this.messageObservables.get(moduleId);
        if (!messageObservable) {
            messageObservable = new Subject();
            this.messageObservables.set(moduleId, messageObservable);
        }
        return messageObservable;
    }
}
传递消息的模块
// 引入服务
constructor(private msgService:MessageService)
// 调用传递消息的方法
this.msgService.Send('user','123');
this.msgService.Send('permission',{ a: 123 });
接受消息的模块
// 引入服务
constructor(private msgService:MessageService)
// 获取传递的消息
this.msgService.On('user', (data) => {
  console.log(data);
})
// 获取传递的消息
this.msgService.On('permission', (data) => {
  console.log(data);
})

因为是Map类型,key重复会被覆盖,使用时尽量避免。

消息传递目前就想到这些,后面有看到再补充。