diff --git a/src/app/demo/pc/table/demo-set.module.ts b/src/app/demo/pc/table/demo-set.module.ts
index f6cfbe00cd..d9eb18e708 100644
--- a/src/app/demo/pc/table/demo-set.module.ts
+++ b/src/app/demo/pc/table/demo-set.module.ts
@@ -109,6 +109,8 @@ import {TableProgressDemoComponent} from "./progress/demo.component";
import {TableProgressDemoModule} from "./progress/demo.module";
import { TableExpandDemoComponent } from './expand/demo.component';
import { TableExpandDemoModule } from './expand/demo.module';
+import { TableExpandTableDemoComponent } from './expand-rows/demo.component';
+import { TableExpandTableDemoModule } from './expand-rows/demo.module';
import { TableUpdateAdditionalColumnDefineDemoComponent } from "./update-additional-column-defines/demo.component";
import { TableUpdateAdditionalColumnDefineDemoModule } from "./update-additional-column-defines/demo.module";
import { TableExpandPageableDemoComponent } from './expand-pageable/demo.component';
@@ -280,6 +282,9 @@ export const routerConfig = [
{
path: 'expand', component: TableExpandDemoComponent
},
+ {
+ path: 'expand-rows', component: TableExpandTableDemoComponent
+ },
{
path: 'expand-pageable', component: TableExpandPageableDemoComponent
},
@@ -303,7 +308,7 @@ export const routerConfig = [
TableNoDataDemoModule, TableHtmlRendererDemoModule, RebuildTableDataDemoModule, TableCellSelectRenderDemoModule, TableMixinTableDemoModule,
TreeTableDemoModule, TableCellEditablePropertyDemoModule,TableDraggableDemoModule, TableUpdateColumnDefinesDemoModule, TableAutoSaveDemoModule,
TableCellRenderFullDemoModule, TableAutoFillUpDemoModule, TableAutoPageableDemoModule, TableColumnWidthDemoModule, TableProgressDemoModule, TableExpandDemoModule,
- TableExpandPageableDemoModule, TableUpdateAdditionalColumnDefineDemoModule
+ TableExpandPageableDemoModule, TableUpdateAdditionalColumnDefineDemoModule, TableExpandTableDemoModule
]
})
export class TableDemoModule {
diff --git a/src/app/demo/pc/table/expand-rows/demo.component.css b/src/app/demo/pc/table/expand-rows/demo.component.css
new file mode 100644
index 0000000000..2abb249c14
--- /dev/null
+++ b/src/app/demo/pc/table/expand-rows/demo.component.css
@@ -0,0 +1,7 @@
+.demo-buttons {
+ margin-bottom: 12px;
+}
+
+.demo-buttons span {
+ margin-right: 4px;
+}
\ No newline at end of file
diff --git a/src/app/demo/pc/table/expand-rows/demo.component.html b/src/app/demo/pc/table/expand-rows/demo.component.html
new file mode 100644
index 0000000000..6aeff70dfd
--- /dev/null
+++ b/src/app/demo/pc/table/expand-rows/demo.component.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+Table Expand
+
+
+ 展开方式
+
+
+
+ 数据更新后是否保持打开
+
+
+
+ 更新数据
+ 重置数据
+ 展开/关闭第三行
+
+
+展开数据发生了变化的行数:{{row}}
+
+信息展示
+
+
\ No newline at end of file
diff --git a/src/app/demo/pc/table/expand-rows/demo.component.ts b/src/app/demo/pc/table/expand-rows/demo.component.ts
new file mode 100644
index 0000000000..b99b503ea6
--- /dev/null
+++ b/src/app/demo/pc/table/expand-rows/demo.component.ts
@@ -0,0 +1,105 @@
+import { Component, ViewChild } from "@angular/core";
+import { TableData, JigsawTable, TableCellSwitchRenderer, TableCellCheckboxRenderer } from "jigsaw/public_api";
+
+@Component({
+ templateUrl: './demo.component.html',
+ styleUrls: ['./demo.component.css']
+})
+export class TableExpandTableDemoComponent {
+ action = ['toggle'];
+ tableData: TableData;
+ remainOpen: boolean = false;
+
+ @ViewChild('tableCmp')
+ tableCmp: JigsawTable;
+
+ row: number;
+
+ constructor() {
+ this.resetData();
+ }
+
+ rowData = [
+ ["cell-1", { data: false, renderer: TableCellSwitchRenderer }, {
+ data: `点击`,
+ renderer: 'html'
+ }, "cell-4", "cell-5", "cell-6", { data: true, renderer: TableCellCheckboxRenderer }],
+ ["cell-1", { data: true, renderer: TableCellSwitchRenderer }, {
+ data: ``,
+ renderer: 'html'
+ }, "cell-4", "cell-5", "cell-6", { data: false, renderer: TableCellCheckboxRenderer }],
+ ["cell-1", { data: false, renderer: TableCellSwitchRenderer, rendererInitData: { valid: false } }, {
+ data: ` 图标`,
+ renderer: 'html'
+ }, "cell-4", "cell-5", "cell-6", { data: false, renderer: TableCellCheckboxRenderer, rendererInitData: { valid: false } }],
+ ["cell-1", { data: true, renderer: TableCellSwitchRenderer, rendererInitData: { disabled: true } }, , {
+ data: `文本`,
+ renderer: 'html'
+ }, "cell-4", "cell-5", "cell-6", { data: true, renderer: TableCellCheckboxRenderer, rendererInitData: { disabled: true } }]
+ ]
+
+ onClick() {
+ alert("按钮被点击了");
+ }
+
+ rowClick(rowIndex: number) {
+ this.tableCmp.expand(rowIndex, this.rowData, this, {
+ remainOpenAfterDataChanges: this.remainOpen, action: this.action[0]
+ });
+ };
+
+ updateData() {
+ this.tableData.fromObject({
+ data: [
+ ["Emily", "", "$15128", "2017/4/21", "HR II", 23, ""],
+ ["Shirley", "", "$11845", "2017/4/25", "R&D Dept II", 42, ""],
+ ["Easton", "", "$17636", "2017/4/24", "Marketing I", 36, ""],
+ ["Emily", "", "$15128", "2017/4/21", "HR II", 65, ""],
+ ["Shirley", "", "$11845", "2017/4/25", "R&D Dept II", 71, ""],
+ ],
+ field: ["name", "switch", "salary", "enroll-date", "office", "progress", "checkbox"],
+ header: ["姓名", "开关组件", "薪资", "入职日期", "部门", "工作进度", "多选框"]
+ })
+ }
+
+ resetData() {
+ this.tableData = new TableData();
+ this.tableData.fromObject({
+ data: [
+ ["Emily", "", "$15128", "2017/4/21", "HR II", 23, ""],
+ ["Shirley", "", "$11845", "2017/4/25", "R&D Dept II", 42, ""],
+ ["Easton", "", "$17636", "2017/4/24", "Marketing I", 36, ""],
+ ["Emily", "", "$15128", "2017/4/21", "HR II", 65, ""],
+ ["Shirley", "", "$11845", "2017/4/25", "R&D Dept II", 71, ""],
+ ["Easton", "", "$17636", "2017/4/24", "Marketing I", 56, ""],
+ ["Emily", "", "$15128", "2017/4/21", "HR II", 17, ""],
+ ["Shirley", "", "$11845", "2017/4/25", "R&D Dept II", 38, ""],
+ ["Easton", "", "$17636", "2017/4/24", "Marketing I", 9, ""],
+ ["Emily", "", "$15128", "2017/4/21", "HR II", 100, ""],
+ ["Shirley", "", "$11845", "2017/4/25", "R&D Dept II", 11, ""],
+ ["Easton", "", "$17636", "2017/4/24", "Marketing I", 82, ""]
+ ],
+ field: ["name", "switch", "salary", "enroll-date", "office", "progress", "checkbox"],
+ header: ["姓名", "开关组件", "薪资", "入职日期", "部门", "工作进度", "多选框"]
+ })
+ }
+
+ expandRow(rowIndex: number) {
+ this.tableCmp.expand(rowIndex, this.rowData, this, {
+ remainOpenAfterDataChanges: this.remainOpen, action: this.action[0]
+ });
+ }
+
+ rowExpandDataChange($event) {
+ this.row = $event.row;
+ }
+
+
+
+
+ // ====================================================================
+ // ignore the following lines, they are not important to this demo
+ // ====================================================================
+ summary: string = '';
+ description: string = '';
+}
diff --git a/src/app/demo/pc/table/expand-rows/demo.module.ts b/src/app/demo/pc/table/expand-rows/demo.module.ts
new file mode 100644
index 0000000000..7965afb68a
--- /dev/null
+++ b/src/app/demo/pc/table/expand-rows/demo.module.ts
@@ -0,0 +1,17 @@
+import {NgModule} from '@angular/core';
+import {
+ JigsawTableModule, JigsawButtonModule, JigsawHeaderModule, JigsawButtonBarModule, JigsawSwitchModule
+} from "jigsaw/public_api";
+import {JigsawDemoDescriptionModule} from "app/demo-description/demo-description";
+import {TableExpandTableDemoComponent} from './demo.component';
+
+@NgModule({
+ imports: [
+ JigsawTableModule, JigsawDemoDescriptionModule, JigsawButtonModule, JigsawHeaderModule,
+ JigsawButtonBarModule, JigsawSwitchModule
+ ],
+ declarations: [TableExpandTableDemoComponent],
+ exports: [TableExpandTableDemoComponent]
+})
+export class TableExpandTableDemoModule {
+}
diff --git a/src/app/demo/pc/table/expand/demo.component.html b/src/app/demo/pc/table/expand/demo.component.html
index 4ab44adc7c..ce251c6a24 100644
--- a/src/app/demo/pc/table/expand/demo.component.html
+++ b/src/app/demo/pc/table/expand/demo.component.html
@@ -4,8 +4,8 @@
-Table
-expand
+Table Expand
+
展开方式
@@ -19,5 +19,7 @@
重置数据
展开/关闭第三行
+
+信息展示
-
+
\ No newline at end of file
diff --git a/src/app/demo/pc/table/expand/demo.component.ts b/src/app/demo/pc/table/expand/demo.component.ts
index 88d85b4b9f..0ce00ed220 100644
--- a/src/app/demo/pc/table/expand/demo.component.ts
+++ b/src/app/demo/pc/table/expand/demo.component.ts
@@ -1,5 +1,5 @@
import { Component, ViewChild } from "@angular/core";
-import { TableData, ColumnDefine, JigsawTable } from "jigsaw/public_api";
+import { TableData, ColumnDefine, JigsawTable, TableCellSwitchRenderer } from "jigsaw/public_api";
@Component({
templateUrl: './demo.component.html',
diff --git a/src/jigsaw/pc-components/table/table.ts b/src/jigsaw/pc-components/table/table.ts
index a7e3368cf1..734b508f42 100644
--- a/src/jigsaw/pc-components/table/table.ts
+++ b/src/jigsaw/pc-components/table/table.ts
@@ -3,6 +3,7 @@
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
+ ComponentFactoryResolver,
ElementRef,
EventEmitter,
Injector,
@@ -15,7 +16,8 @@
QueryList,
Renderer2,
ViewChild,
- ViewChildren
+ ViewChildren,
+ ApplicationRef
} from "@angular/core";
import {CommonModule} from "@angular/common";
import {Subscription} from "rxjs";
@@ -23,7 +25,7 @@ import {TranslateModule, TranslateService} from "@ngx-translate/core";
import {PerfectScrollbarDirective, PerfectScrollbarModule} from "ngx-perfect-scrollbar";
import {AbstractJigsawComponent, JigsawCommonModule, WingsTheme} from "../../common/common";
import {JigsawTableCellInternalComponent, JigsawTableHeaderInternalComponent} from "./table-inner.components";
-import {TableData} from "../../common/core/data/table-data";
+import {TableData, TableDataMatrix} from "../../common/core/data/table-data";
import {AffixUtils, InternalUtils} from "../../common/core/utils/internal-utils";
import {
_getColumnIndex,
@@ -58,10 +60,10 @@ import {TableUtils} from "./table-utils";
})
export class JigsawTable extends AbstractJigsawComponent implements OnInit, AfterViewInit, OnDestroy {
- constructor(private _renderer: Renderer2, private _elementRef: ElementRef,
- protected _zone: NgZone, private _changeDetectorRef: ChangeDetectorRef,
- // @RequireMarkForCheck 需要用到,勿删
- private _injector: Injector) {
+ constructor(private _renderer: Renderer2, private _elementRef: ElementRef, protected _zone: NgZone, private _changeDetectorRef: ChangeDetectorRef,
+ private _componentFactoryResolver: ComponentFactoryResolver, private _applicationRef: ApplicationRef,
+ // @RequireMarkForCheck 需要用到,勿删
+ private _injector: Injector) {
super();
if (CommonUtils.getBrowserType() == 'Firefox') {
this._$isFFBrowser = true;
@@ -151,6 +153,8 @@ export class JigsawTable extends AbstractJigsawComponent implements OnInit, Afte
public selectedRowChange: EventEmitter = new EventEmitter();
@Output()
public rowExpand: EventEmitter = new EventEmitter();
+ @Output()
+ public rowExpandDataChange = new EventEmitter<{ row: number, data: TableDataMatrix }>();
private _getColumnIndex(field: string): [number, TableData] {
return _getColumnIndex(this.data, this._additionalData, field);
@@ -905,7 +909,7 @@ export class JigsawTable extends AbstractJigsawComponent implements OnInit, Afte
/**
* 展开行
*/
- public expand(rowIndex: number, rawHtml: string, rawHtmlContext?: object, options?: TableRowExpandOptions): void {
+ public expand(rowIndex: number, rawHtml: string | TableDataMatrix, rawHtmlContext?: object, options?: TableRowExpandOptions): void {
const rowElement = this._rowElementRefs.toArray()[rowIndex]?.nativeElement;
if (!rowElement) {
return;
@@ -926,9 +930,11 @@ export class JigsawTable extends AbstractJigsawComponent implements OnInit, Afte
// 已经打开了,但此时人家要求再打开,需要更新一下内容
const rowInfo = this._allExpandedRows.find(i => i?.element === rowElement.nextSibling);
rowInfo.remainOpen = options?.remainOpenAfterDataChanges;
- rowInfo.element.children[0].innerHTML = TrustedHtmlHelper.updateHtml(
- CommonUtils.isUndefined(rawHtml) ? "" : rawHtml, rawHtmlContext, []);
- return;
+ if (typeof rawHtml === 'string') {
+ rowInfo.element.children[0].innerHTML = TrustedHtmlHelper.updateHtml(
+ CommonUtils.isUndefined(rawHtml) ? "" : rawHtml, rawHtmlContext, []);
+ return;
+ }
}
if (!expanded && action == 'show') {
// 该行还没打开,人家要求打开
@@ -948,26 +954,107 @@ export class JigsawTable extends AbstractJigsawComponent implements OnInit, Afte
private _allExpandedRows: { element: HTMLTableRowElement, remainOpen: boolean, rowIndex: number, currentPage: number }[] = [];
- private _showExpansion(rowElement: HTMLTableRowElement, rawHtml: string, context: object, remainOpen: boolean, rowIndex: number): void {
- const tr = document.createElement('tr');
- const trustedEle = document.createElement('td');
- const headerEle = this._headerComponents.toArray();
- trustedEle.colSpan = headerEle.length;
- tr.classList.add('jigsaw-table-row-expansion');
- tr.insertBefore(trustedEle, tr.lastElementChild);
-
- const trustedHtml = CommonUtils.isUndefined(rawHtml) ? "" : rawHtml;
- trustedEle.innerHTML = TrustedHtmlHelper.updateHtml(trustedHtml, context, []);
- rowElement.parentNode.insertBefore(tr, rowElement.nextSibling);
- const data: IPageable = this.data;
- const currentPage = data?.pagingInfo instanceof PagingInfo ? data.pagingInfo.currentPage : undefined;
- this._allExpandedRows.push({ element: tr, rowIndex, remainOpen, currentPage });
+ private _showExpansion(rowElement: HTMLTableRowElement, rawHtml: string | TableDataMatrix, context: object, remainOpen: boolean, rowIndex: number): void {
+ if (typeof rawHtml === 'string') {
+
+ const tr = document.createElement('tr');
+ const trustedEle = document.createElement('td');
+ const headerEle = this._headerComponents.toArray();
+ trustedEle.colSpan = headerEle.length;
+ tr.classList.add('jigsaw-table-row-expansion');
+ tr.insertBefore(trustedEle, tr.lastElementChild);
+
+ const trustedHtml = CommonUtils.isUndefined(rawHtml) ? "" : rawHtml;
+ trustedEle.innerHTML = TrustedHtmlHelper.updateHtml(trustedHtml, context, []);
+ rowElement.parentNode.insertBefore(tr, rowElement.nextSibling);
+ const data: IPageable = this.data;
+ const currentPage = data?.pagingInfo instanceof PagingInfo ? data.pagingInfo.currentPage : undefined;
+ this._allExpandedRows.push({ element: tr, rowIndex, remainOpen, currentPage });
+ }
+
+ if (rawHtml instanceof Array) {
+ const tableData = new TableData();
+ const data = [];
+ const field = [];
+
+ rawHtml.forEach(row => {
+ const rowData = [];
+ row.forEach((cell, colIndex) => {
+ if (CommonUtils.isUndefined(cell.data)) {
+ rowData.push(cell);
+ } else {
+ rowData.push(cell.data)
+ }
+ field.push('row-expand-field' + colIndex)
+ })
+ data.push(rowData);
+ })
+
+ tableData.fromObject({
+ data: data,
+ field: field,
+ header: field
+ })
+
+ tableData.onRefresh(() => {
+ this.rowExpandDataChange.emit({ row: rowIndex, data: tableData.data })
+ })
+
+ const trEleArr = [];
+ rawHtml.forEach((row, rowIndex) => {
+ const tr = document.createElement('tr');
+ tr.classList.add('jigsaw-table-row-expansion');
+
+ row.forEach((cell, colIndex) => {
+ const td = document.createElement('td');
+
+ if (cell.renderer === 'html') {
+ const trustedHtml = CommonUtils.isUndefined(cell.data) ? "" : cell.data;
+ td.innerHTML = TrustedHtmlHelper.updateHtml(trustedHtml, context, []);
+ tr.appendChild(td);
+ return;
+ }
+
+ let factory = this._componentFactoryResolver.resolveComponentFactory(JigsawTableCellInternalComponent);
+ const componentRef = factory.create(this._injector, [], td);
+ let cellSettings = cell;
+ if (typeof cell === 'string') {
+ cellSettings = {
+ renderer: DefaultCellRenderer,
+ data: cell
+ }
+ }
+
+ componentRef.instance.field = 'row-expand-field' + colIndex;
+ componentRef.instance.row = rowIndex;
+ componentRef.instance.tableData = tableData;
+ componentRef.instance.additionalData = new TableData();
+ componentRef.instance.renderer = cellSettings.renderer;
+ componentRef.instance.rendererInitData = cellSettings.rendererInitData;
+ componentRef.instance.cellData = cellSettings.data;
+ this._applicationRef.attachView(componentRef.hostView);
+ tr.appendChild(td);
+ })
+ trEleArr.push(tr);
+ })
+
+ trEleArr.reverse().forEach(tr => {
+ rowElement.parentNode.insertBefore(tr, rowElement.nextSibling);
+ const data: IPageable = this.data;
+ const currentPage = data?.pagingInfo instanceof PagingInfo ? data.pagingInfo.currentPage : undefined;
+ this._allExpandedRows.push({ element: tr, rowIndex, remainOpen, currentPage });
+ })
+ }
}
private _hideExpansion(rowElement: HTMLTableRowElement): void {
const index = this._allExpandedRows.findIndex(i => i?.element === rowElement.nextSibling);
+ if (index == -1) {
+ return;
+ }
this._allExpandedRows.splice(index, 1);
rowElement.nextSibling.remove();
+ this._hideExpansion(rowElement);
}
private _clearExpansion() {