环境:
Angular 4.0.0
Angular2 Material2 2.0.0-beta.3
node v7.4.0
npm 4.0.5
1.多选列表组件
1)定义组件
multiple.component.ts
import { Component, OnInit, HostListener, Input } from '@angular/core';
@Component({
selector: 'multiple',
templateUrl: 'multiple.component.html',
styleUrls: ['_multiple.component.scss']
})
export class MultipleComponent implements OnInit {
@Input() items: any = {};
@Input() colsTitle: any;
@Input() keyArray: any;
@Input() assignFilterItem: string;
constructor() {
}
public ngOnInit() {
this.keyArray = this.keyArray.split(",");
this.colsTitle = this.colsTitle.split(",");
}
// 设置全选状态
private setSelectedAll = function() {
// 全选
let data = this.items;
let count = 0;
for (let i in data) {
if (data[i].checked) {
count++;
}
}
if (count === data.length) {
this.slideToggleModel = true;
} else {
this.slideToggleModel = false;
}
}
// 选中,反选
onToggle(item) {
item.checked = !item.checked;
this.setSelectedAll();
}
// 在已选项列表中取消选中
cancleSelected(item) {
item.checked = false;
this.setSelectedAll();
}
// 全选
selectAll(checked) {
var data = this.items;
if (checked) {
for (var i in data) {
data[i].checked = true;
}
} else {
for (var i in data) {
data[i].checked = false;
}
}
}
}
multiple.component.html
<div class="clearfix">
<div class="col-md-12">
<md-input-container>
<input mdInput placeholder="请键入筛选项..." value="" [(ngModel)]="searchText"></md-input-container>
</div>
<div class="col-md-12 multiple-data-list">
<md-grid-list [cols]=colsTitle.length+1 rowHeight="35px">
<md-grid-tile>
<md-slide-toggle (change)="selectAll(slideToggleModel)" [(ngModel)]="slideToggleModel" [checked]="slideToggleModel">全选</md-slide-toggle>
</md-grid-tile>
<md-grid-tile class="text-center" *ngFor="let title of colsTitle">
<h3>{{title}}</h3>
</md-grid-tile>
<div *ngFor="let item of items | searchTextFilter: [searchText, assignFilterItem]">
<md-grid-tile>
<md-checkbox (change)="onToggle(item)" [checked]="item.checked"></md-checkbox>
</md-grid-tile>
<md-grid-tile *ngFor="let key of keyArray">{{item[key]}}</md-grid-tile>
</div>
</md-grid-list>
</div>
<div class="col-md-12">
<h2 class="multiple-title">已选项</h2>
<div class="multiple-selected">
<div class="multiple-selected-item" *ngFor="let item of items">
<md-chip *ngIf="item.checked" [selected]="item.checked" class="chip-item" hover (click)="cancleSelected(item)">
<span class="chip-item-label">{{item[assignFilterItem]}}</span> <i class="icon-close-cyan selectedItem-close"></i>
</md-chip>
</div>
</div>
</div>
</div>
2)使用方法
在标签<multiple></multiple>设置相应属性
属性 | 描述 |
---|---|
items | 数据源 |
colsTitle | string,列表的表头。eg. colsTitle="Title,Name" |
keyArray | string,列表的列项内容属性。eg. keyArray="title,name" |
assignFilterItem | <ol><li>string, searchText筛选的属性。<br />eg.数据源的属性为:title,name,number 假设输入searchText需要筛选的是Title,则assignFilterItem="title";</li><li>已选项展示的值,assignFilterItem="title", 即设置已选项展示的数据是title的值。</li></ol> |
3)例子
multiple-example.component.html
<multiple [items]="listData" colsTitle="Title" keyArray="title" assignFilterItem="title"></multiple>
效果图:
2.简单版多选列表组件
逻辑上,跟1.多选列表组件其实是类似的。就是使用上有区别。
1)定义组件
multipleSimple.component.ts
import { Component, OnInit, HostListener, Input } from '@angular/core';
@Component({
selector: 'multipleSimple',
templateUrl: 'multipleSimple.component.html',
styleUrls: ['_multiple.component.scss']
})
export class MultipleSimpleComponent implements OnInit {
public ngOnInit() { }
@Input() items: any = {};
@Input() assignFilterItem: string;
slideToggleModel: boolean;
// 设置全选状态
private setSelectedAll = function() {
// 全选
let data = this.items;
let count = 0;
for (let i in data) {
if (data[i].selected) {
count++;
}
}
if (count === data.length) {
this.slideToggleModel = true;
} else {
this.slideToggleModel = false;
}
}
// 选中,反选
onToggle(item) {
item.selected = !item.selected;
this.setSelectedAll();
}
// 在已选项列表中取消选中
cancleSelected(item) {
item.selected = false;
this.setSelectedAll();
}
// 全选
selectAll(checked) {
var data = this.items;
if (checked) {
for (var i in data) {
data[i].selected = true;
}
} else {
for (var i in data) {
data[i].selected = false;
}
}
}
}
multipleSimple.component.html
<div class="clearfix">
<div class="col-md-12">
<md-input-container>
<input mdInput placeholder="请键入筛选项..." value="" [(ngModel)]="searchText"></md-input-container>
<md-slide-toggle (change)="selectAll(slideToggleModel)" [(ngModel)]="slideToggleModel" [checked]="slideToggleModel">全选</md-slide-toggle>
</div>
<div class="col-md-2">
<h3 class="multiple-title">请选择</h3>
<md-list>
<md-list-item *ngFor="let item of items | searchTextFilter: [searchText,assignFilterItem]">
<md-chip-list>
<md-chip class="chip-item-unselect" [selected]="item.selected" (click)="onToggle(item)">{{item[assignFilterItem]}}</md-chip>
</md-chip-list>
</md-list-item>
</md-list>
</div>
<div class="col-md-3">
<h3 class="multiple-title">已选项</h3>
<md-list>
<span *ngFor="let item of items">
<md-chip *ngIf="item.selected" [selected]="item.selected" class="chip-item" hover (click)="cancleSelected(item)">
<span class="chip-item-label">{{item[assignFilterItem]}}</span> <i class="icon-close-cyan selectedItem-close"></i>
</md-chip>
</span>
</md-list>
</div>
</div>
2)使用方法
在标签<multipleSimple></multipleSimple>设置相应属性
属性 | 描述 |
---|---|
items | 数据源 |
assignFilterItem | <ol><li>string, searchText筛选的属性。<br />eg.数据源的属性为:title,name,number 假设输入searchText需要筛选的是Title,则assignFilterItem="title";</li><li>列表的列项内容属性</li><li>已选项展示的值,assignFilterItem="title", 即设置已选项展示的数据是title的值。</li></ol> |
3)例子
multiple-example.component.html
<multipleSimple [items]="datas" assignFilterItem="title"></multipleSimple>
效果图:
3.多选Dialog
1)定义组件
multipleDialog.component.ts
import { Component, OnInit, Inject } from '@angular/core';
import { MdDialogRef } from '@angular/material';
import { MD_DIALOG_DATA } from '@angular/material';
@Component({
selector: 'multiple-dialog',
styleUrls: ['_multiple.component.scss'],
templateUrl: 'multipleDialog.component.html'
})
export class MultipleDialogComponent implements OnInit {
config: {};
slideToggleModel: boolean;
constructor(private mdDialogRef: MdDialogRef<MultipleDialogComponent>, @Inject(MD_DIALOG_DATA) data: any) {
this.config = data;
this.setSelectedAll();
}
// 设置全选状态
private setSelectedAll = function() {
// 全选
let data = this.config.content;
let count = 0;
for (let i in data) {
if (data[i].checked) {
count++;
}
}
if (count === data.length) {
this.slideToggleModel = true;
} else {
this.slideToggleModel = false;
}
}
public ngOnInit() {
}
// 选中,反选
onToggle(item) {
item.checked = !item.checked;
this.setSelectedAll();
}
// 在已选项列表中取消选中
cancleSelected(item) {
item.checked = false;
this.setSelectedAll();
}
// 全选
selectAll(checked) {
let data: any = this.config;
let dataContent: any = data.content;
console.log(dataContent);
if (checked) {
for (let i in dataContent) {
dataContent[i].checked = true;
}
} else {
for (let i in dataContent) {
dataContent[i].checked = false;
}
}
}
}
multipleDialog.component.html
<div md-dialog-title>
<md-input-container>
<input mdInput placeholder="请键入筛选项..." value="" [(ngModel)]="searchText"></md-input-container>
<span class="icon-close-mid pull-right md-dialog-title-close" (click)="mdDialogRef.close()"></span>
</div>
<div md-dialog-content class="multiple-dialog-contentContainer">
<div class="col-md-12 multiple-data-list">
<md-grid-list [cols]=config.colsTitle.length+1 rowHeight="35px">
<md-grid-tile>
<md-slide-toggle (change)="selectAll(slideToggleModel)" [(ngModel)]="slideToggleModel" [checked]="slideToggleModel">全选</md-slide-toggle>
</md-grid-tile>
<md-grid-tile class="text-center" *ngFor="let title of config.colsTitle">{{title}}</md-grid-tile>
<div *ngFor="let item of config.content | searchTextFilter: [searchText, config.assignFilterItem]">
<md-grid-tile>
<md-checkbox (change)="onToggle(item)" [checked]="item.checked"></md-checkbox>
</md-grid-tile>
<md-grid-tile *ngFor="let key of config.keyArrayName">{{item[key]}}</md-grid-tile>
</div>
</md-grid-list>
</div>
<div class="col-md-12">
<h2 class="multiple-title">已选项</h2>
<div class="multiple-selected">
<div class="multiple-selected-item" *ngFor="let item of config.content">
<md-chip *ngIf="item.checked" [selected]="item.checked" class="chip-item" hover (click)="cancleSelected(item)">
<span class="chip-item-label">{{item[config.assignFilterItem]}}</span> <i class="icon-close-cyan selectedItem-close"></i>
</md-chip>
</div>
</div>
</div>
</div>
<div md-dialog-actions class="multiple-dialog-actionsContainer">
<md-slide-toggle (change)="selectAll(slideToggleModel)" [(ngModel)]="slideToggleModel" [checked]="slideToggleModel">全选</md-slide-toggle>
<div class="multiple-dialog-operate">
<button md-raised-button color="primary" (click)="mdDialogRef.close()">确定</button>
<button md-raised-button md-dialog-close class="multiple-dialog-cancel">取消</button>
</div>
</div>
2)把组件注入到服务
为了通用,把组件注入服务,方便在其他地方使用。这样的话,就不用在每次使用的时候重新定义组件。
multipleDialog.service.ts
import { Component, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
import { MdDialog, MdDialogRef, MdDialogConfig } from '@angular/material';
import { MultipleDialogComponent } from './multipleDialog.component';
import { Observable } from 'rxjs/Observable';
export class MultipleDialogService {
constructor( @Inject(MdDialog) public _multipleDialog: MdDialog, @Inject(DOCUMENT) doc: any) {
_multipleDialog.afterOpen.subscribe((ref: MdDialogRef<any>) => {
if (!doc.body.classList.contains('no-scroll')) {
doc.body.classList.add('no-scroll');
}
});
_multipleDialog.afterAllClosed.subscribe(() => {
doc.body.classList.remove('no-scroll');
});
}
public setMultipleData(contentOrConfig: any, title?: string): Observable<any> {
let config = new MdDialogConfig();
config = {
width: '700px'
};
if (contentOrConfig instanceof Object) {
config.data = contentOrConfig;
} else if ((typeof contentOrConfig) === 'string') {
config.data = {
content: contentOrConfig,
title: title
}
}
return this._multipleDialog.open(MultipleDialogComponent, config).afterClosed();
}
}
3)使用方法
-
Step1:在标签中添加方法,并传入参数
属性 | 描述 |
---|---|
arg1 | Array,列表的表头。eg. ['Title'] |
arg2 | Array,列表的列项内容的属性。eg. ['title'] |
arg3 | <ol><li>string, searchText筛选的属性。<br />eg.数据源的属性为:title,name,number 假设输入searchText需要筛选的是Title,则assignFilterItem="title";</li><li>已选项展示的值,即设置已选项展示的数据是title的值。</li></ol> |
-
Step2:在需要使用的组件里的provides注册并定义相应的方法
4)例子
multiple-example.component.html
<button md-raised-button (click)="openDialog(['Title'], ['title'],'title')">Open dialog</button>
multiple-example.component.ts
import { Component, OnInit, HostListener } from '@angular/core';
import { MultipleDialogService } from './multipleDialog.service';
@Component({
selector: 'multipleExample',
templateUrl: 'multiple-example.component.html',
styleUrls: ['multiple-example.component.css'],
providers: [MultipleDialogService]
})
export class MultipleExampleComponent implements OnInit {
public constructor(public _multipleDialogService: MultipleDialogService) { }
public ngOnInit() { }
listData = [{ title: '森美', name: '1' }, { title: '小仪' }, { title: '西瓜' }, { title: '阿杰' }];
// 多选框
public openDialog(titleArray, keyArray, assignFilterItemName) {
this._multipleDialogService.setMultipleData({ content: this.listData, colsTitle: titleArray, keyArrayName: keyArray, assignFilterItem: assignFilterItemName }).subscribe(res => {
// 返回结果
let selectedArr = [];
let data: any = this.listData;
for (let i in data) {
if (data[i].checked) {
selectedArr.push(data[i]);
}
}
});
}
}
效果图:
4.简单多选Dialog
逻辑上,跟3.多选Dialog组件其实是类似的。只是简单版
1)定义组件
multipleSimpleDialog..component.ts
import { Component, OnInit, Inject } from '@angular/core';
import { MdDialogRef } from '@angular/material';
import { MD_DIALOG_DATA } from '@angular/material';
@Component({
selector: 'multiple-dialog',
styleUrls: ['_multiple.component.scss'],
templateUrl: 'multipleSimpleDialog.component.html'
})
export class MultipleSimpleDialogComponent implements OnInit {
config: {};
slideToggleModel: boolean;
constructor(private mdDialogRef: MdDialogRef<MultipleSimpleDialogComponent>, @Inject(MD_DIALOG_DATA) data: any) {
this.config = data;
this.setSelectedAll();
}
// 设置全选状态
private setSelectedAll = function() {
// 全选
let data = this.config.content;
let count = 0;
for (let i in data) {
if (data[i].selected) {
count++;
}
}
if (count === data.length) {
this.slideToggleModel = true;
} else {
this.slideToggleModel = false;
}
}
public ngOnInit() {
}
// 选中,反选
onToggle(item) {
item.selected = !item.selected;
this.setSelectedAll();
}
// 在已选项列表中取消选中
cancleSelected(item) {
item.selected = false;
this.setSelectedAll();
}
// 全选
selectAll(checked) {
let data: any = this.config;
let dataContent: any = data.content;
if (checked) {
for (let i in dataContent) {
dataContent[i].selected = true;
}
} else {
for (let i in dataContent) {
dataContent[i].selected = false;
}
}
}
}
multipleSimpleDialog.component.html
<div md-dialog-title>
<md-input-container>
<input mdInput placeholder="请键入筛选项..." value="" [(ngModel)]="searchText"></md-input-container>
<span class="icon-close-mid pull-right md-dialog-title-close" (click)="mdDialogRef.close()"></span>
</div>
<div md-dialog-content class="multiple-dialog-contentContainer">
<div class="col-md-6">
<h3 class="multiple-title">请选择</h3>
<md-list>
<md-list-item *ngFor="let item of config.content | searchTextFilter: [searchText,config.assignFilterItem]">
<md-chip-list>
<md-chip class="chip-item-unselect" [selected]="item.selected" (click)="onToggle(item)">{{item[config.assignFilterItem]}}</md-chip>
</md-chip-list>
</md-list-item>
</md-list>
</div>
<div class="col-md-6">
<h3 class="multiple-title">已选项</h3>
<md-list>
<span *ngFor="let item of config.content">
<md-chip *ngIf="item.selected" [selected]="item.selected" class="chip-item" hover (click)="cancleSelected(item)">
<span class="chip-item-label">{{item[config.assignFilterItem]}}</span> <i class="icon-close-cyan selectedItem-close" (click)="cancleSelected(item)"></i>
</md-chip>
</span>
</md-list>
</div>
</div>
<div md-dialog-actions class="multiple-dialog-actionsContainer">
<md-slide-toggle (change)="selectAll(slideToggleModel)" [(ngModel)]="slideToggleModel" [checked]="slideToggleModel">全选</md-slide-toggle>
<div class="multiple-dialog-operate">
<button md-raised-button color="primary" (click)="mdDialogRef.close()">{{ config.button || '确定' }}</button>
<button md-raised-button md-dialog-close class="multiple-dialog-cancel">取消</button>
</div>
</div>
2)把组件注入到服务
为了通用,把组件注入服务,方便在其他地方使用。这样的话,就不用在每次使用的时候重新定义组件。
multipleSimpleDialog.service.ts
import { Component, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
import { MdDialog, MdDialogRef, MdDialogConfig } from '@angular/material';
import { MultipleSimpleDialogComponent } from './multipleSimpleDialog.component';
import { Observable } from 'rxjs/Observable';
export class MultipleSimpleDialogService {
constructor( @Inject(MdDialog) public _multipleDialog: MdDialog, @Inject(DOCUMENT) doc: any) {
_multipleDialog.afterOpen.subscribe((ref: MdDialogRef<any>) => {
if (!doc.body.classList.contains('no-scroll')) {
doc.body.classList.add('no-scroll');
}
});
_multipleDialog.afterAllClosed.subscribe(() => {
doc.body.classList.remove('no-scroll');
});
}
public setMultipleData(contentOrConfig: any, title?: string): Observable<any> {
let config = new MdDialogConfig();
config = {
width: '700px'
};
if (contentOrConfig instanceof Object) {
config.data = contentOrConfig;
} else if ((typeof contentOrConfig) === 'string') {
config.data = {
content: contentOrConfig,
title: title
}
}
return this._multipleDialog.open(MultipleSimpleDialogComponent, config).afterClosed();
}
}
3)使用方法
-
Step1:在标签中添加方法,并传入参数
属性 | 描述 |
---|---|
arg1 | <ol><li>string, searchText筛选的属性。<br />eg.数据源的属性为:title,name,number 假设输入searchText需要筛选的是Title,则assignFilterItem="title";</li><li>列表的内容</li><li>已选项展示的值,即设置已选项展示的数据是title的值。</li></ol> |
-
Step2:在需要使用的组件里的provides注册并定义相应的方法
4)例子
multiple-example.component.html
<button md-raised-button (click)="openSimpleDialog('title')">Open Simple dialog</button>
multiple-example.component.ts
import { Component, OnInit, HostListener } from '@angular/core';
import { MultipleSimpleDialogService } from './multipleSimpleDialog.service';
@Component({
selector: 'multipleExample',
templateUrl: 'multiple-example.component.html',
styleUrls: ['multiple-example.component.css'],
providers: [MultipleSimpleDialogService]
})
export class MultipleExampleComponent implements OnInit {
public constructor(public _multipleSimpleDialogService: MultipleSimpleDialogService) { }
public ngOnInit() { }
datas = [{ title: '你', name: '1' }, { title: 'Banana' }, { title: 'Cat' }, { title: 'Dog', name: '1' }, { title: 'Egg' }, { title: 'Food' }, { title: 'Girl', name: '1' }, { title: 'Hello' }, { title: 'In' }];
// 简单多选框
public openSimpleDialog(assignFilterItemName) {
this._multipleSimpleDialogService.setMultipleData({ content: this.datas, assignFilterItem: assignFilterItemName }).subscribe(res => {
// 返回结果
let selectedArr = [];
let data: any = this.datas;
for (let i in data) {
if (data[i].selected) {
selectedArr.push(data[i]);
}
}
// console.log(selectedArr);
});
}