angular 实现下拉列表组件

栏目: JavaScript · 发布时间: 5年前

内容简介:需求:最开始就是用最简单的方法,前台请求数据,然后通过select和option在页面上显示,但是写了一会儿发现出现了许多类似下面的

需求:

angular 实现下拉列表组件

方案一

最开始就是用最简单的方法,前台请求数据,然后通过select和option在页面上显示,但是写了一会儿发现出现了许多类似下面的 重复的代码

// 初始化年级选项
initGradeOptions() {
    this.gradeService.getAll().subscribe((res) => {
        this.gradeOptions = res;
    }, () => {
        console.log('get gradeOption error');
    });
}
<nz-select nzPlaceHolder="请选择所属年级" formControlName="grade">
   <nz-option *ngFor="let grade of gradeOptions" [nzLabel]="grade.name"
              [nzValue]="grade"></nz-option>
</nz-select>

每写一个列表都要写请求它的数据的方法和模板中的内容,非常繁琐。

方案二

因为在项目中,不止一个地方用到了这样的列表,所以就想着把这些列表单独拿出来,写成组件。

这里就参考了朴世超组长的angular的输入与输出写了这个组件

思路大概如下:

angular 实现下拉列表组件

ts:

@Input() defaultValue: Grade;                       // 选中的值
@Output() selected = new EventEmitter<number>();    // 输出属性
datas: Grade[];                                     // 所有数据

constructor(private gradeService: GradeService) {
}

// 请求所有的数据
ngOnInit() {
    this.gradeService.getAll().subscribe((res) => {
        this.datas = res;
    }, () => {
        console.log('error');
    });
}

// 当则内容更改时,将已选中对象的id弹射到父组件绑定的事件上
dataChange() {
    this.selected.emit(this.defaultValue);
}

html:

<nz-select nzPlaceHolder="所属年级" class="wide" [(ngModel)]="defaultValue" (ngModelChange)="dataChange()">
<nz-option *ngFor="let data of datas" [nzLabel]="data.name"
           [nzValue]="data"></nz-option>
 </nz-select>

ps: 默认选中的功能还在完善,待更新

思考

当我照着上面的套路继续写 collegeList , majorList , klassList ,以后还会有 teacherList , studentList 等等,这样不也形成了很多重复的代码吗?

于是我就想能不能设计一个组件:

我让它是什么列表,它就是什么列表。

然后我就寻找这几个组件的共性,发现它们请求数据的的特点:

  • 都是使用get请求
  • 返回的数据都是数组
  • url只有最后一项不同

那么,我只要传给组件一个url数组,就能根据url请求对应的数据,再生成相应的模板

方案三(失败)

angular 实现下拉列表组件

angular 实现下拉列表组件

子组件ts:

@Input() urls: String[][] = [];                 // 保存传递过来的url
datas: String[][] = [];                         // 保存查询结果
@Input() titles: String[][] = [];               // 保存提示语句
@Output() selectItems = new EventEmitter();     // 已选中的对象
index = 0;
items = [];

constructor(public dataService: DataService) {
}


ngOnInit() {
    this.getData(this.index);
}

getData(index: number): void {
    if (index < this.urls.length) {
        const url = this.urls[index];
        this.dataService.getAllData(url).subscribe((res) => {
            this.datas[index] = res;
            console.log(this.datas);
        }, () => {
            console.log('error');
        });
    }
}

dataChange(i: number) {
    console.log(this.items);
    this.selectItems.emit(this.items);
    this.getData(i + 1);
}

子组件html:

<nz-select [nzPlaceHolder]="titles[i]"
       style="width: 150px;"
       (ngModelChange)="dataChange(i)"
       [(ngModel)]="items[i]"
       *ngFor="let url of urls,let i = index">
<nz-option *ngFor="let item of datas[i]" [nzValue]="item" [nzLabel]="item.name">        
</nz-option>
</nz-select>

父组件ts:

url = ['Grade', 'College', 'Major'];
titels = ['年级', '学院', '专业'];

getSelectItems(event) {
    console.log(event);
}

父组件html:

<app-grade-list 
        [urls]="url" 
        [titles]="titels" 
        (selectItems)="getSelectItems($event)">
        </app-grade-list>

效果:

angular 实现下拉列表组件

看起来还能用,但是再往后写就发现这样写有致命的缺陷。

需要查找url
不知道数据与实体的对应关系
不易维护

总结

虽然这些下拉列表有一定的共性,并且可以抽象出一些公共的功能来实现,但本身设计略复杂,且使用效果并不好,最后还是放弃了第三个方案。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Defensive Design for the Web

Defensive Design for the Web

37signals、Matthew Linderman、Jason Fried / New Riders / 2004-3-2 / GBP 18.99

Let's admit it: Things will go wrong online. No matter how carefully you design a site, no matter how much testing you do, customers still encounter problems. So how do you handle these inevitable bre......一起来看看 《Defensive Design for the Web》 这本书的介绍吧!

html转js在线工具
html转js在线工具

html转js在线工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具