UNPKG

@rdkmaster/jigsaw-labs

Version:

Jigsaw, the next generation component set for RDK

215 lines (179 loc) 7.3 kB
import {AbstractJigsawComponent} from "../common"; import {ControlValueAccessor} from "@angular/forms"; import {AfterContentInit, ChangeDetectorRef, EventEmitter, Input, OnDestroy, Output, QueryList} from "@angular/core"; import {CallbackRemoval, CommonUtils} from "../../core/utils/common-utils"; import {ArrayCollection} from "../../core/data/array-collection"; export class GroupOptionValue { [index: string]: any; disabled?: boolean; } export class AbstractJigsawGroupComponent extends AbstractJigsawComponent implements ControlValueAccessor, AfterContentInit, OnDestroy { protected _removeRefreshCallback: CallbackRemoval; @Input() public valid: boolean = true; //设置对象的标识 private _trackItemBy: string[] = []; @Input() public get trackItemBy(): string | string[] { return this._trackItemBy; } public set trackItemBy(value: string | string[]) { this._trackItemBy = typeof value === 'string' ? value.split(/\s*,\s*/g) : value; } //判断是否支持多选 @Input() public multipleSelect: boolean; protected _selectedItems = new ArrayCollection<any>(); @Input() public get selectedItems(): ArrayCollection<any> | any[] { return this._selectedItems; } public set selectedItems(newValue: ArrayCollection<any> | any[]) { this.writeValue(newValue); if (this._selectedItems === newValue) { return; } this._propagateChange(newValue); this._removeInvalidSelectedItems(); } private _removeInvalidSelectedItems():void { if (!this._items || !this._selectedItems) { return; } this._selectedItems.forEach(selectedItem => { if (this._items.find(item => CommonUtils.compareWithKeyProperty(item.value, selectedItem, this._trackItemBy))) { return; } this._selectedItems.splice(this.selectedItems.indexOf(selectedItem), 1); }); } @Output() public selectedItemsChange = new EventEmitter<any[]>(); //获取映射的items protected _items: QueryList<AbstractJigsawOptionComponent>; protected _updateSelectItems(itemValue, selected): void { if (this.multipleSelect) { //多选 if (selected) { this.selectedItems.push(itemValue); } else { this._selectedItems.forEach(selectedItemValue => { if (CommonUtils.compareWithKeyProperty(selectedItemValue, itemValue, this._trackItemBy)) { this._selectedItems.splice(this.selectedItems.indexOf(selectedItemValue), 1); } }); } } else { //单选选中 this._items.length && this._items.forEach((item: AbstractJigsawOptionComponent) => { //去除其他option选中 if (!CommonUtils.compareWithKeyProperty(item.value, itemValue, this._trackItemBy) && item.selected) { item.selected = false; item.changeDetector.detectChanges(); this._selectedItems.splice(this.selectedItems.indexOf(item.value), 1); } }); //添加选中数据 this.selectedItems.push(itemValue); } this._removeInvalidSelectedItems(); this._selectedItems.refresh(); this.selectedItemsChange.emit(this.selectedItems); } //根据选中的item更新selectedItems protected _updateSelectItemsForForm(itemValue, selected): void { this._updateSelectItems(itemValue, selected); this._propagateChange(this.selectedItems); } public update(itemValue, selected) { this._updateSelectItemsForForm(itemValue, selected); } //根据selectedItems设置选中的option protected _setItemState(items: QueryList<AbstractJigsawOptionComponent>): void { if (!(this.selectedItems instanceof ArrayCollection) || !items.length) { return; } this.callLater(() => { items.forEach(item => { let hasSelected = false; this._selectedItems.forEach(selectedItem => { if (CommonUtils.compareWithKeyProperty(item.value, selectedItem, this._trackItemBy)) { hasSelected = true; } }); item.selected = hasSelected; }); }); } private _subscribeItemSelectedChange(items: QueryList<AbstractJigsawOptionComponent>) { items.forEach(item => { // 取消可能重复的订阅事件 item.change.observers.length = 0; item.change.subscribe(() => { if (this.multipleSelect) { //多选 item.selected = !item.selected;//切换组件选中状态 this._updateSelectItemsForForm(item.value, item.selected); } else { //单选 if (!item.selected) { item.selected = true; this._updateSelectItemsForForm(item.value, item.selected); } } }) }); } ngAfterContentInit() { this._setItemState(this._items); this._subscribeItemSelectedChange(this._items); this._items.changes.subscribe(items => { // 异步变更data数据 this._setItemState(items); this._subscribeItemSelectedChange(items); this._removeInvalidSelectedItems(); }); if(this._items.length) { // 在本地数据为空时,不检查无用选项 this._removeInvalidSelectedItems(); } } ngOnDestroy() { super.ngOnDestroy(); if (this._removeRefreshCallback) { this._removeRefreshCallback() } if(this._items) { this._items.forEach(item => item.change.unsubscribe()); } } protected _propagateChange: any = () => { }; protected _setSelectedItems(newValue: any): void { if (this._selectedItems === newValue) { return; } newValue = newValue instanceof ArrayCollection ? newValue : new ArrayCollection(newValue); this._selectedItems = newValue; if (this.initialized) { this._setItemState(this._items); } if (this._removeRefreshCallback) { this._removeRefreshCallback() } this._removeRefreshCallback = newValue.onRefresh(() => this._setItemState(this._items)); } public writeValue(newValue: any): void { this._setSelectedItems(newValue); } public registerOnChange(fn: any): void { this._propagateChange = fn; } public registerOnTouched(fn: any): void { } } export class AbstractJigsawOptionComponent extends AbstractJigsawComponent { @Input() public value: any; @Input() public disabled: boolean = false; @Output() public selectedChange = new EventEmitter<boolean>(); @Input() public selected: boolean = false; // 选中状态 @Output() public change = new EventEmitter<AbstractJigsawOptionComponent>(); public changeDetector: ChangeDetectorRef }