找回密码
 立即注册
首页 业界区 业界 Util 应用框架 UI 全新升级

Util 应用框架 UI 全新升级

眺愤 2025-6-9 08:58:45
Util UI 已经开发多年, 并在多家公司的项目使用.
不过一直以来, Util UI 存在一些缺陷, 始终未能解决.
最近几个月, Util 团队下定决心, 终于彻底解决了所有已知缺陷.
Util 应用框架 UI 介绍

Util 应用框架 UI 建立在 Angular , Ng-Zorro, Ng-Alain 基础之上, 用于开发企业中后台.
Util 应用框架 UI 的特点


  • 简洁

    Util UI 通常可以将复杂组件的 html 代码量压缩 3 - 10 倍,从而使项目的可维护性大幅提升.
    下面以查询表单为例进行对比.
    先看效果演示.
    1.gif

    Util UI 的标签使用 TagHelper 进行封装 ,代码如下.
    1. <util-card borderless="true" >
    2.     <i nz-icon="" nzType="setting"></i><util-search-form label-width="120">
    3.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-row gutter="24">
    4.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    5.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-input id="code" name="code"  ng-model="queryParam.code" label-text="identity.application.code"/>
    6.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    7.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    8.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-input id="name" name="name"  ng-model="queryParam.name" label-text="identity.application.name"/>
    9.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    10.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    11.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-select id="enabled" name="enabled"  ng-model="queryParam.enabled" label-text="identity.application.enabled"/>
    12.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    13.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    14.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-input id="remark" name="remark"  ng-model="queryParam.remark" label-text="identity.application.remark"/>
    15.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    16.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    17.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    18.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-range-picker id="begin_creation_time" name="begin_creation_time"  
    19.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>label-text="util.beginCreationTime"
    20.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>begin-date="queryParam.beginCreationTime" end-date="queryParam.endCreationTime"/>
    21.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    22.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    23.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-range-picker id="begin_last_modification_time" name="begin_last_modification_time"
    24.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>label-text="util.beginLastModificationTime"
    25.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>begin-date="queryParam.beginLastModificationTime" end-date="queryParam.endLastModificationTime" />
    26.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    27.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column >
    28.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-flex justify="FlexEnd" align="Center" gap="Small">
    29.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-button id="btnRefresh" icon="Sync" on-click="refresh(btnRefresh)" text-reset="true"></util-button>
    30.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-button id="btnQuery" type="Primary" icon="Search" on-click="query(btnQuery)" text-query="true"></util-button>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>
    31.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-a is-search="true" ></util-a>
    32.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-flex>
    33.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    34.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-row>
    35.     <i nz-icon="" nzType="setting"></i></util-search-form>
    36. </util-card>
    复制代码
    上面的标签会转换成 Ng Zorro 原生的 html 标签.
    1.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'identity.application.code'|i18n}}    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'identity.application.name'|i18n}}    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'identity.application.enabled'|i18n}}<util-card borderless="true" >
    2.     <i nz-icon="" nzType="setting"></i><util-search-form label-width="120">
    3.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-row gutter="24">
    4.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    5.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-input id="code" name="code"  ng-model="queryParam.code" label-text="identity.application.code"/>
    6.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    7.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    8.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-input id="name" name="name"  ng-model="queryParam.name" label-text="identity.application.name"/>
    9.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    10.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    11.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-select id="enabled" name="enabled"  ng-model="queryParam.enabled" label-text="identity.application.enabled"/>
    12.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    13.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    14.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-input id="remark" name="remark"  ng-model="queryParam.remark" label-text="identity.application.remark"/>
    15.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    16.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    17.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    18.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-range-picker id="begin_creation_time" name="begin_creation_time"  
    19.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>label-text="util.beginCreationTime"
    20.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>begin-date="queryParam.beginCreationTime" end-date="queryParam.endCreationTime"/>
    21.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    22.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    23.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-range-picker id="begin_last_modification_time" name="begin_last_modification_time"
    24.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>label-text="util.beginLastModificationTime"
    25.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>begin-date="queryParam.beginLastModificationTime" end-date="queryParam.endLastModificationTime" />
    26.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    27.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column >
    28.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-flex justify="FlexEnd" align="Center" gap="Small">
    29.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-button id="btnRefresh" icon="Sync" on-click="refresh(btnRefresh)" text-reset="true"></util-button>
    30.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-button id="btnQuery" type="Primary" icon="Search" on-click="query(btnQuery)" text-query="true"></util-button>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>
    31.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-a is-search="true" ></util-a>
    32.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-flex>
    33.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    34.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-row>
    35.     <i nz-icon="" nzType="setting"></i></util-search-form>
    36. </util-card>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'identity.application.remark'|i18n}}    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'util.beginCreationTime'|i18n}}    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'util.beginLastModificationTime'|i18n}}    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'util.reset'|i18n}}    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'util.query'|i18n}}    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{expand?('util.collapse'|i18n):('util.expand'|i18n)}}    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>
    复制代码
    是 Util UI 的查询表单标签.
    查询表单支持响应式,并将按钮区域始终放置在最后一行的右侧.
    label-width 是一个扩展的范围设置属性, 为每个表单组件的  设置  样式, 避免了分别设置每个组件的宽度.
    Ng Zorro 表单组件由  ,  ,  组合而成.
    和  设置了 label-text , 这是一个扩展属性,它会激活  结构的自动创建.
    是文本框, 除了为它自动创建  结构, 还会添加清除内容的功能.
    Util UI 大多常用组件的显示文本会自动添加 i18n 管道, 比如 'identity.application.code'|i18n ,用于支持多语言.
    从前面的示例可以看到 Util UI 可以大幅提升 html 标签的书写效率, 降低维护成本.
  • 易用

    Util 对常用功能进行了高度封装, 并提供简单易用的 API.
    易用性是 Util UI 封装的关键目标,也是 Util UI 存在的意义.
    本文后续将以最近更新的一个关键功能 - 表格设置, 演示易用性.
  • 强类型提示

    Util UI 提供的标签使用 TagHelper 技术封装, 支持强类型提示.
    如果你使用 Vs Code 开发, Util UI 标签提示信息大致与 Ng Zorro Vs Code 插件提示效果相当.
    Vs Code 的标签提示信息并不精准, 包含很多与 html 相关的属性, 比如 aria- 打头的属性就占了几屏, 这降低了代码提示的作用.
    2.png

    如果使用 Vs 开发, 甚至安装了 Resharper , 代码提示就能达到最佳效果.
    3.png

  • 持续更新和改进

    Util UI 不仅仅是对 Ng Zorro 功能的简单包装, 更提供了常用功能的扩展.
    Util UI 扩展功能来自之前使用其它 UI 框架的经验, 另外收集项目开发时的实际需求,并加以整理,以满足使用 Util UI 的项目.
    Util 团队倾听开发人员的心声, 并持续改进, 从而更好的满足项目需求.
Util 应用框架 UI 的封装实现方式


  • 使用 .cshtml 替代 .html 页面.

    .cshtml 是 .Net 提供的一种高级 html 封装技术.
    Util 创造性的将 .cshtml 引入 Angular 应用开发.
    Util 将 cshtml 页面作为 html 抽象层, 用来隐藏 html 的复杂性.
    Ng Zorro 组件库定义了大量的 Angular 组件.
    使用 Angular 组件, 就是在 html 页面中书写自定义的标签.
    Util 应用框架使用 TagHelper 对 Ng Zorro 标签进行封装, 以提供更加简洁的用法.
    TagHelper 是一种 .Net 标签, 在 .cshtml 文件中使用.
    虽然 TagHelper 标签看上去也是一些自定义标签 , 但它们不是 Angular 组件.
    Util 会在开发阶段将 .cshtml 文件转换成 html.
  • 使用 Angular 指令进行扩展.

    Ng Zorro 组件库与 EasyUI 这样的组件库具有显著差异.
    Ng Zorro 组件库提供的 API 具有粒度细, 扩展性强的特点.
    Ng Zorro 组件的很多功能并不内置于组件中,而是通过 Demo 的形式告诉你怎么使用.
    这为你提供了很大的灵活性和自由.
    但也意味着,如果你不加封装,直接在项目中复制使用, 就会造成大量的冗余代码, 降低项目的可维护性.
    要扩展 Ng Zorro 组件, 仅使用 TagHelper 封装 html 是不够的, 还需要找到编写脚本的地方.
    封装和扩展 Ng Zorro 组件, 通常有两种方式.

    • 一种方式是创建新的 Angular 组件对原始组件进行包装.
      使用组件包装, 可以提供更加易用的 Api.
      不过这种封装方式也有一些缺陷.

      • 新组件的 API 与原始组件可能不同, 增加了学习成本.
      • 由于需要将原始组件的 API 暴露出来 , 导致更多的冗余代码.
      • 扩展性降低.
        对于表格这样复杂的组件, html 结构相当复杂, 使用组件包装通常不会保留原有的 html 结构.
        扩展点完全由新组件控制, 从而降低扩展性.

    • 另一种方式是使用 Angular 指令对原始组件进行扩展.
      Angular 指令使用起来就像标签上的属性一样.
      使用 Angular 指令进行扩展, 最大优势是保留原始组件的全部用法, 不会降低其扩展性.
      当然指令封装方式也带来了新的挑战,那就是 html 标签会更加复杂.
      Util UI 使用 Angular 指令进行封装扩展, 并使用 TagHelper 标签来隐藏 html 的复杂度.

  • Lambda表达式支持

    在 .cshtml 文件中使用 TagHelper 标签, 你可以直接设置标签上的属性.
    不过 , 如果使用 .Net 开发 API 后端, 并创建了 DTO 对象, 你可以将 DTO 属性直接绑定到标签上.
    下面演示查询表单组件如何使用Lambda表达式绑定 DTO 属性.
    DTO 代码如下:
    1. /// <summary>
    2. /// 应用程序查询参数
    3. /// </summary>
    4. public class ApplicationQuery : QueryParameter {
    5.     <i nz-icon="" nzType="setting"></i>/// <summary>
    6.     <i nz-icon="" nzType="setting"></i>/// 应用程序编码
    7.     <i nz-icon="" nzType="setting"></i>///</summary>
    8.     <i nz-icon="" nzType="setting"></i>[Description( "identity.application.code" )]
    9.     <i nz-icon="" nzType="setting"></i>public string Code { get; set; }
    10.     <i nz-icon="" nzType="setting"></i>/// <summary>
    11.     <i nz-icon="" nzType="setting"></i>/// 应用程序名称
    12.     <i nz-icon="" nzType="setting"></i>///</summary>
    13.     <i nz-icon="" nzType="setting"></i>[Description( "identity.application.name" )]
    14.     <i nz-icon="" nzType="setting"></i>public string Name { get; set; }
    15.     <i nz-icon="" nzType="setting"></i>/// <summary>
    16.     <i nz-icon="" nzType="setting"></i>/// 启用
    17.     <i nz-icon="" nzType="setting"></i>///</summary>
    18.     <i nz-icon="" nzType="setting"></i>[Description( "identity.application.enabled" )]
    19.     <i nz-icon="" nzType="setting"></i>public bool? Enabled { get; set; }
    20.     <i nz-icon="" nzType="setting"></i>/// <summary>
    21.     <i nz-icon="" nzType="setting"></i>/// 备注
    22.     <i nz-icon="" nzType="setting"></i>///</summary>
    23.     <i nz-icon="" nzType="setting"></i>[Description( "identity.application.remark" )]
    24.     <i nz-icon="" nzType="setting"></i>public string Remark { get; set; }
    25.     <i nz-icon="" nzType="setting"></i>/// <summary>
    26.     <i nz-icon="" nzType="setting"></i>/// 起始创建时间
    27.     <i nz-icon="" nzType="setting"></i>/// </summary>
    28.     <i nz-icon="" nzType="setting"></i>[Display( Name = "util.beginCreationTime" )]
    29.     <i nz-icon="" nzType="setting"></i>public DateTime? BeginCreationTime { get; set; }
    30.     <i nz-icon="" nzType="setting"></i>/// <summary>
    31.     <i nz-icon="" nzType="setting"></i>/// 结束创建时间
    32.     <i nz-icon="" nzType="setting"></i>/// </summary>
    33.     <i nz-icon="" nzType="setting"></i>[Display( Name = "util.endCreationTime" )]
    34.     <i nz-icon="" nzType="setting"></i>public DateTime? EndCreationTime { get; set; }
    35.     <i nz-icon="" nzType="setting"></i>/// <summary>
    36.     <i nz-icon="" nzType="setting"></i>/// 起始最后修改时间
    37.     <i nz-icon="" nzType="setting"></i>/// </summary>
    38.     <i nz-icon="" nzType="setting"></i>[Display( Name = "util.beginLastModificationTime" )]
    39.     <i nz-icon="" nzType="setting"></i>public DateTime? BeginLastModificationTime { get; set; }
    40.     <i nz-icon="" nzType="setting"></i>/// <summary>
    41.     <i nz-icon="" nzType="setting"></i>/// 结束最后修改时间
    42.     <i nz-icon="" nzType="setting"></i>/// </summary>
    43.     <i nz-icon="" nzType="setting"></i>[Display( Name = "util.endLastModificationTime" )]
    44.     <i nz-icon="" nzType="setting"></i>public DateTime? EndLastModificationTime { get; set; }
    45. }
    复制代码
    .cshtml 代码如下:
    1. @model ApplicationQuery<util-card borderless="true" >
    2.     <i nz-icon="" nzType="setting"></i><util-search-form label-width="120">
    3.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-row gutter="24">
    4.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    5.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-input id="code" name="code"  ng-model="queryParam.code" label-text="identity.application.code"/>
    6.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    7.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    8.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-input id="name" name="name"  ng-model="queryParam.name" label-text="identity.application.name"/>
    9.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    10.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    11.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-select id="enabled" name="enabled"  ng-model="queryParam.enabled" label-text="identity.application.enabled"/>
    12.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    13.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    14.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-input id="remark" name="remark"  ng-model="queryParam.remark" label-text="identity.application.remark"/>
    15.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    16.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    17.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    18.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-range-picker id="begin_creation_time" name="begin_creation_time"  
    19.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>label-text="util.beginCreationTime"
    20.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>begin-date="queryParam.beginCreationTime" end-date="queryParam.endCreationTime"/>
    21.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    22.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column>
    23.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-range-picker id="begin_last_modification_time" name="begin_last_modification_time"
    24.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>label-text="util.beginLastModificationTime"
    25.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>begin-date="queryParam.beginLastModificationTime" end-date="queryParam.endLastModificationTime" />
    26.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    27.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-column >
    28.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-flex justify="FlexEnd" align="Center" gap="Small">
    29.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-button id="btnRefresh" icon="Sync" on-click="refresh(btnRefresh)" text-reset="true"></util-button>
    30.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-button id="btnQuery" type="Primary" icon="Search" on-click="query(btnQuery)" text-query="true"></util-button>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>
    31.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-a is-search="true" ></util-a>
    32.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-flex>
    33.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-column>
    34.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-row>
    35.     <i nz-icon="" nzType="setting"></i></util-search-form>
    36. </util-card>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>
    复制代码
    Lambda表达式会读取 DTO 对象的元数据, 并自动设置常用属性, 从而再次大幅提升生产力.
Util 应用框架 UI 的组成


  • Util.Ui.NgZorro

    Util.Ui.NgZorro 类库包含 Ng Zorro TagHelper 标签, 目前已封装官方正式发布的全部组件.
  • Util.Ui.NgAlain

    Util.Ui.NgAlain 类库包含 Ng Alain 部分组件 TagHelper 标签.
  • util-angular

    util-angular 是一个 typescript 脚本库, 包含 Ng Zorro 扩展指令和常用操作 Helper.
Util 应用框架 UI 最新进展

Util 应用框架 UI 最近进行了全面改进,并取得了重大突破.
最大的进展有2点, 一是开发机制的改进, 二是增加了表格设置功能.

  • 开发机制改进

    • 架构缺陷

      Util 应用框架将 .cshtml 文件引入 Angular 已有相当长的年头.
      由于这种非主流的用法并没有微软官方的支持,所以一直存在相当多的问题.

      • 最主要的影响是导致开发阶段运行缓慢.
        之前的开发流程, Angular 组件在开发阶段直接访问 cshtml 页面,所以开发阶段必须使用 Angular JIT 模式, 它比 Angular AOT 模式要慢一些.
        cshtml 在第一次访问时, 尚未创建缓存 , 会比较慢.
        Angular 应用启动时,将访问根模块引用的所有页面, 所以启动时会产生相当的卡顿.
        这个问题通过 Angular 延迟加载模块得到缓解.
        如果项目比较大,包含数十个业务模块, 将每个业务模块创建为延迟加载模块.
        当应用启动时, 并不会访问所有页面, 只有请求了某个业务模块的功能, 才会访问该模块包含的 cshtml 页面.
        不过从 Angular 13 开始, Angular 移除了传统的视图引擎, 导致上述开发方式无法使用延迟加载模块.
        这意味着所有业务模块在开发阶段必须在根模块中引用.
        Angular 应用启动后将访问所有 cshtml 页面, 这显然是不可接受的.
        一种可行的解决办法是使用微前端方案.
        微前端架构将业务模块分离到不同的项目从而减少应用启动时间.
        一些较大的项目和团队使用微前端架构是合适的.
        但微前端架构具有复杂性, 使用微前端架构代替延迟加载模块则非常牵强.
        这是 Util 团队进行全面改造的根本原因.
      • 另一个影响是项目结构比较复杂.
        Util 采用的项目结构最早来自 .Net Core Angular 项目模板, 并加以修改.
        Angular 应用被放在 ClientApp 目录中.
        .cshtml 文件则被放在 Pages 目录中.
        这导致组件与模板的对应关系比较复杂.

    • 改进方案

      很多时候, 解决问题最重要是思路的转变.
      之前的架构缺陷主要来自在开发阶段让 Angular 组件直接请求 cshtml 页面,从而与原生 Angular 应用产生差别.
      不过, Util 使用 cshtml 仅限于开发阶段, 发布之后实际上与 cshtml 没有任何关系.
      cshtml 的作用只是帮助生成 html 而已.
      现代化开发一个重要的功能是热更新, 比如 Angular 应用, 它会持续监视你的相关文件.
      当你编辑完 .ts 或 .html 文件时, 浏览器就会自动刷新.
      如果我们监视所有 .cshtml 文件,并在保存 cshtml 文件时自动生成对应的 html 文件,就能从根本上解决问题.
      由于只需要处理保存的 cshtml 文件, 生成 html 的速度将非常迅速.
      当 html 生成完成, 后续流程则与原生 angular 应用相同, 从而解决引入 cshtml 相关的所有缺陷.
      现在, 编辑并保存 .cshtml 文件, 浏览器就会自动刷新, 与原生 Angular 应用相比, 大致慢几百毫秒, 通常可以忽略不计.
      项目结构复杂的问题则很好解决, 将 .cshtml 与 Angular 组件放在一起即可.
      这与原生 Angular 应用相似, 只需修改 .cshtml 生成 html 文件的路径规则.
      一直以来, Util UI的架构比较臃肿, 只能在 Vs 中开发.
      但现在前端基本都使用 Vs Code.
      最新 UI 架构与原生 Angular 应用差别很小, 同样适合使用 Vs Code 开发.
      下面是使用 Vs Code 打开的项目结构.
      4.png


  • 表格设置

    表格是业务系统的基石.
    我们收集了一些项目上使用 Ng Zorro 表格的反馈意见.

    • 当表格列较多时,如果不进行宽度设置, 则会显示得很畸形.
      要解决这个问题, 需要设置表格 nzScroll 属性的 x 值.
      nzScroll 的 x 可以让表格产生横向的滚动条, 从而将表格内容拉伸.
      不过这个值应该设置成多少合适, 则是一门学问.
      通常需要计算表格中有多少列,每列大致占多少宽度, nzScroll.x 的值大致是这些宽度之和.
      手工计算宽度费时费力, 最好是能自动计算.
    • 另一个问题是冻结表格头, 并让表格在一定高度滚动.
      通过设置 nzScroll 属性的 y 值可以做到这一点.
      不过设置 nzScroll.y 也是一门学问, 因为不同屏幕大小可能需要设置不同的值,在开发阶段很难固定.
      一些公司使用某些方法计算以达到自适应高度,不过大多针对比较固定的页面布局,且相对简单.
      更好的办法是让用户在运行时根据自己的要求动态更新.
    • 除了表格的总宽度, 每个列的宽度设置也是一个头痛的问题.
      列宽大多与内容相关, 在开发阶段设置固定列宽, 当内容超过固定宽度就会出现换行,影响美观.
      如果在开发阶段设置一个默认宽度, 并在运行时可由用户修改就能解决问题.
      当然最好能支持拖动表头修改列宽, 则更为方便.
    • 自定义列是很多项目的必备功能.
      当表格列非常多, 用户希望只显示其中感兴趣的一部分列, 并能修改列的显示顺序.
      Ng Zorro 支持自定义列功能, 不过使用起来比较复杂.
      当你启用了自定义列, 用来固定左右侧的 nzLeft 和 nzRight 就变得不那么利索.
      列与列之间经常会出现一些缝隙或对不齐的现象, Ng Zorro 官方文档给出了一些调整建议, 不过也是非常麻烦.
    • 诸如表格批量编辑,表格行编辑, 树形异步加载等需求都是很早之前就已经扩展支持, 就不在此一一列出.
    下面介绍 Util UI 表格设置功能.
    先来一个表格设置的效果图.
    5.gif

    可以看到, 它确实解决了前面提到的棘手问题.
    如何开启表格设置功能?
    表格标签示例代码.
    1. @*表格*@
    2. <util-table id="tb" key="identity_operation" enable-table-settings="true"
    3.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>show-checkbox="true" show-line-number="true"
    4.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>url="operation" query-param="queryParam" sort="SortId">
    5.     <i nz-icon="" nzType="setting"></i><util-td for="Name"></util-td>
    6.     <i nz-icon="" nzType="setting"></i><util-td for="Uri"></util-td>
    7.     <i nz-icon="" nzType="setting"></i><util-td for="IsBase" sort="false"></util-td>
    8.     <i nz-icon="" nzType="setting"></i><util-td for="Remark"></util-td>
    9.     <i nz-icon="" nzType="setting"></i><util-td for="Enabled">
    10.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-tag color-type="GeekBlue" ng-if="row.enabled" text-enabled="true"></util-tag>
    11.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-tag color-type="Red" ng-if="!row.enabled" text-not-enabled="true"></util-tag>
    12.     <i nz-icon="" nzType="setting"></i></util-td>
    13.     <i nz-icon="" nzType="setting"></i><util-td for="CreationTime"></util-td>
    14.     <i nz-icon="" nzType="setting"></i><util-td for="LastModificationTime"></util-td>
    15.     <i nz-icon="" nzType="setting"></i><util-td title-operation="true">
    16.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-a on-click="openDetailDialog(row)" text-detail="true"></util-a>
    17.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-container acl="operation.update">
    18.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-divider type="Vertical"></util-divider>
    19.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-a on-click="openEditDrawer(row)" text-update="true"></util-a>
    20.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-container>
    21.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-container acl="operation.delete">
    22.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-divider type="Vertical"></util-divider>
    23.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><util-a danger="true" on-click="delete(row.id)" text-delete="true"></util-a>
    24.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></util-container>
    25.     <i nz-icon="" nzType="setting"></i></util-td>
    26. </util-table>
    复制代码
    要开启表格设置功能, 只需要在  标签设置 enable-table-settings 属性为 true.
    你可能要问, 需要编写 ts 脚本代码吗?
    不用 !!!
    如果你看过 Ng Zorro 官方自定义列的示例, 知道需要将一个 NzCustomColumn[] 对象传入 的 nzCustomColumn 属性.
    那么, Util UI 的自定义列功能是否使用 Ng Zorro 官方的实现呢?
    下面来看看生成的 html , 答案就会揭晓.
    1. <nz-table #tb="" #x_tb="xTableExtend" (nzPageIndexChange)="x_tb.pageIndexChange($event)"
    2.     <i nz-icon="" nzType="setting"></i>(nzPageSizeChange)="x_tb.pageSizeChange($event)" order="SortId" url="operation" x-table-extend=""
    3.     <i nz-icon="" nzType="setting"></i>[(nzPageIndex)]="x_tb.queryParam.page" [(nzPageSize)]="x_tb.queryParam.pageSize" [(queryParam)]="queryParam"
    4.     <i nz-icon="" nzType="setting"></i>[nzBordered]="ts_tb.bordered" [nzCustomColumn]="ts_tb.columns" [nzData]="x_tb.dataSource"
    5.     <i nz-icon="" nzType="setting"></i>[nzFrontPagination]="false" [nzLoading]="x_tb.loading" [nzPageSizeOptions]="x_tb.pageSizeOptions"
    6.     <i nz-icon="" nzType="setting"></i>[nzScroll]="ts_tb.scroll" [nzShowQuickJumper]="true" [nzShowSizeChanger]="true" [nzShowTotal]="total_tb"
    7.     <i nz-icon="" nzType="setting"></i>[nzSize]="ts_tb.size" [nzTotal]="x_tb.total">
    8.     <i nz-icon="" nzType="setting"></i><thead>
    9.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><tr>
    10.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><th (nzCheckedChange)="x_tb.masterToggle()" nzCellControl="util.checkbox"
    11.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzChecked]="x_tb.isMasterChecked()" [nzDisabled]="!x_tb.dataSource.length"
    12.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzIndeterminate]="x_tb.isMasterIndeterminate()" [nzLeft]="ts_tb.isLeft('util.checkbox')"
    13.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('util.checkbox')" [nzShowCheckbox]="true"
    14.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[titleAlign]="ts_tb.getTitleAlign('util.checkbox')">
    15.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></th>
    16.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><th nzCellControl="util.lineNumber" [nzLeft]="ts_tb.isLeft('util.lineNumber')"
    17.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('util.lineNumber')" [titleAlign]="ts_tb.getTitleAlign('util.lineNumber')">
    18.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'util.lineNumber'|i18n}}
    19.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></th>
    20.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><th (nzResizeEnd)="ts_tb.handleResize($event,'identity.operation.name')"
    21.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>(nzSortOrderChange)="x_tb.sortChange('name',$event)" nz-resizable="" nzBounds="window"
    22.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>nzCellControl="identity.operation.name" nzPreview="" [nzLeft]="ts_tb.isLeft('identity.operation.name')"
    23.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('identity.operation.name')" [nzShowSort]="true" [nzSortFn]="true"
    24.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[titleAlign]="ts_tb.getTitleAlign('identity.operation.name')">
    25.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'identity.operation.name'|i18n}}
    26.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-resize-handle nzDirection="right"></nz-resize-handle>
    27.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></th>
    28.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><th (nzResizeEnd)="ts_tb.handleResize($event,'identity.operation.uri')"
    29.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>(nzSortOrderChange)="x_tb.sortChange('uri',$event)" nz-resizable="" nzBounds="window"
    30.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>nzCellControl="identity.operation.uri" nzPreview="" [nzLeft]="ts_tb.isLeft('identity.operation.uri')"
    31.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('identity.operation.uri')" [nzShowSort]="true" [nzSortFn]="true"
    32.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[titleAlign]="ts_tb.getTitleAlign('identity.operation.uri')">
    33.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'identity.operation.uri'|i18n}}
    34.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-resize-handle nzDirection="right"></nz-resize-handle>
    35.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></th>
    36.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><th (nzResizeEnd)="ts_tb.handleResize($event,'identity.operation.isBase')" nz-resizable="" nzBounds="window"
    37.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>nzCellControl="identity.operation.isBase" nzPreview=""
    38.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('identity.operation.isBase')"
    39.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('identity.operation.isBase')"
    40.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[titleAlign]="ts_tb.getTitleAlign('identity.operation.isBase')">
    41.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'identity.operation.isBase'|i18n}}
    42.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-resize-handle nzDirection="right"></nz-resize-handle>
    43.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></th>
    44.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><th (nzResizeEnd)="ts_tb.handleResize($event,'identity.operation.remark')"
    45.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>(nzSortOrderChange)="x_tb.sortChange('remark',$event)" nz-resizable="" nzBounds="window"
    46.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>nzCellControl="identity.operation.remark" nzPreview=""
    47.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('identity.operation.remark')"
    48.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('identity.operation.remark')" [nzShowSort]="true" [nzSortFn]="true"
    49.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[titleAlign]="ts_tb.getTitleAlign('identity.operation.remark')">
    50.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'identity.operation.remark'|i18n}}
    51.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-resize-handle nzDirection="right"></nz-resize-handle>
    52.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></th>
    53.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><th (nzResizeEnd)="ts_tb.handleResize($event,'identity.operation.enabled')"
    54.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>(nzSortOrderChange)="x_tb.sortChange('enabled',$event)" nz-resizable="" nzBounds="window"
    55.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>nzCellControl="identity.operation.enabled" nzPreview=""
    56.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('identity.operation.enabled')"
    57.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('identity.operation.enabled')" [nzShowSort]="true" [nzSortFn]="true"
    58.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[titleAlign]="ts_tb.getTitleAlign('identity.operation.enabled')">
    59.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'identity.operation.enabled'|i18n}}
    60.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-resize-handle nzDirection="right"></nz-resize-handle>
    61.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></th>
    62.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><th (nzResizeEnd)="ts_tb.handleResize($event,'util.creationTime')"
    63.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>(nzSortOrderChange)="x_tb.sortChange('creationTime',$event)" nz-resizable="" nzBounds="window"
    64.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>nzCellControl="util.creationTime" nzPreview="" [nzLeft]="ts_tb.isLeft('util.creationTime')"
    65.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('util.creationTime')" [nzShowSort]="true" [nzSortFn]="true"
    66.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[titleAlign]="ts_tb.getTitleAlign('util.creationTime')">{{'util.creationTime'|i18n}}
    67.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-resize-handle nzDirection="right"></nz-resize-handle>
    68.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></th>
    69.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><th (nzResizeEnd)="ts_tb.handleResize($event,'util.lastModificationTime')"
    70.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>(nzSortOrderChange)="x_tb.sortChange('lastModificationTime',$event)" nz-resizable="" nzBounds="window"
    71.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>nzCellControl="util.lastModificationTime" nzPreview=""
    72.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('util.lastModificationTime')"
    73.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('util.lastModificationTime')" [nzShowSort]="true" [nzSortFn]="true"
    74.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[titleAlign]="ts_tb.getTitleAlign('util.lastModificationTime')">
    75.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'util.lastModificationTime'|i18n}}
    76.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-resize-handle nzDirection="right"></nz-resize-handle>
    77.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></th>
    78.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><th (nzResizeEnd)="ts_tb.handleResize($event,'util.operation')" nz-resizable="" nzBounds="window"
    79.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>nzCellControl="util.operation" nzPreview="" [nzLeft]="ts_tb.isLeft('util.operation')"
    80.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('util.operation')" [titleAlign]="ts_tb.getTitleAlign('util.operation')">
    81.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'util.operation'|i18n}}
    82.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-resize-handle nzDirection="right"></nz-resize-handle>
    83.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></th>
    84.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></tr>
    85.     <i nz-icon="" nzType="setting"></i></thead>
    86.     <i nz-icon="" nzType="setting"></i><tbody>
    87.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><tr *ngFor="let row of x_tb.dataSource;index as index">
    88.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><td (click)="$event.stopPropagation()" (nzCheckedChange)="x_tb.toggle(row)" nzCellControl="util.checkbox"
    89.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzAlign]="ts_tb.getAlign('util.checkbox')" [nzChecked]="x_tb.isChecked(row)"
    90.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('util.checkbox')" [nzRight]="ts_tb.isRight('util.checkbox')"
    91.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzShowCheckbox]="true">
    92.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></td>
    93.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><td nzCellControl="util.lineNumber" [nzAlign]="ts_tb.getAlign('util.lineNumber')"
    94.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('util.lineNumber')" [nzRight]="ts_tb.isRight('util.lineNumber')">
    95.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{row.lineNumber}}
    96.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></td>
    97.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><td nzCellControl="identity.operation.name" [nzAlign]="ts_tb.getAlign('identity.operation.name')"
    98.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzEllipsis]="ts_tb.getEllipsis('identity.operation.name')"
    99.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('identity.operation.name')" [nzRight]="ts_tb.isRight('identity.operation.name')">
    100.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{row.name}}
    101.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></td>
    102.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><td nzCellControl="identity.operation.uri" [nzAlign]="ts_tb.getAlign('identity.operation.uri')"
    103.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzEllipsis]="ts_tb.getEllipsis('identity.operation.uri')"
    104.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('identity.operation.uri')" [nzRight]="ts_tb.isRight('identity.operation.uri')">
    105.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{row.uri}}
    106.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></td>
    107.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><td nzCellControl="identity.operation.isBase" [nzAlign]="ts_tb.getAlign('identity.operation.isBase')"
    108.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzEllipsis]="ts_tb.getEllipsis('identity.operation.isBase')"
    109.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('identity.operation.isBase')"
    110.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('identity.operation.isBase')">
    111.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><i *ngIf="!row.isBase" nz-icon nzType="close"></i>
    112.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><i *ngIf="row.isBase" nz-icon nzType="check"></i>
    113.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></td>
    114.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><td nzCellControl="identity.operation.remark" [nzAlign]="ts_tb.getAlign('identity.operation.remark')"
    115.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzEllipsis]="ts_tb.getEllipsis('identity.operation.remark')"
    116.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('identity.operation.remark')"
    117.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('identity.operation.remark')">
    118.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{row.remark}}
    119.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></td>
    120.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><td nzCellControl="identity.operation.enabled" [nzAlign]="ts_tb.getAlign('identity.operation.enabled')"
    121.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzEllipsis]="ts_tb.getEllipsis('identity.operation.enabled')"
    122.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('identity.operation.enabled')"
    123.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('identity.operation.enabled')">
    124.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-tag *ngIf="row.enabled" nzColor="geekblue">{{'util.enabled'|i18n}}</nz-tag>
    125.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-tag *ngIf="!row.enabled" nzColor="red">{{'util.notEnabled'|i18n}}</nz-tag>
    126.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></td>
    127.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><td nzCellControl="util.creationTime" [nzAlign]="ts_tb.getAlign('util.creationTime')"
    128.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzEllipsis]="ts_tb.getEllipsis('util.creationTime')" [nzLeft]="ts_tb.isLeft('util.creationTime')"
    129.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('util.creationTime')">
    130.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{row.creationTime|date:'yyyy-MM-dd HH:mm'}}
    131.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></td>
    132.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><td nzCellControl="util.lastModificationTime" [nzAlign]="ts_tb.getAlign('util.lastModificationTime')"
    133.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzEllipsis]="ts_tb.getEllipsis('util.lastModificationTime')"
    134.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzLeft]="ts_tb.isLeft('util.lastModificationTime')"
    135.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('util.lastModificationTime')">
    136.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{row.lastModificationTime|date:'yyyy-MM-dd HH:mm'}}
    137.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></td>
    138.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><td nzCellControl="util.operation" [nzAlign]="ts_tb.getAlign('util.operation')"
    139.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzEllipsis]="ts_tb.getEllipsis('util.operation')" [nzLeft]="ts_tb.isLeft('util.operation')"
    140.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>[nzRight]="ts_tb.isRight('util.operation')">
    141.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'util.detail'|i18n}}
    142.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><ng-container *aclIf="'operation.update'">
    143.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-divider nzType="vertical"></nz-divider>
    144.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'util.update'|i18n}}
    145.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></ng-container>
    146.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><ng-container *aclIf="'operation.delete'">
    147.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i><nz-divider nzType="vertical"></nz-divider>
    148.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>{{'util.delete'|i18n}}
    149.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></ng-container>
    150.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></td>
    151.     <i nz-icon="" nzType="setting"></i>    <i nz-icon="" nzType="setting"></i></tr>
    152.     <i nz-icon="" nzType="setting"></i></tbody>
    153. </nz-table>
    154. <ng-template #total_tb="" let-range="range" let-total="">
    155.     <i nz-icon="" nzType="setting"></i>{{ 'util.tableTotalTemplate'|i18n:{start:range[0],end:range[1],total:total} }}
    156. </ng-template>
    157. <x-table-settings #ts_tb=""
    158.     <i nz-icon="" nzType="setting"></i>key="identity_operation" [enableFixedColumn]="true"
    159.     <i nz-icon="" nzType="setting"></i>[initColumns]="[{'title':'util.checkbox','width':x_tb.config.table.checkboxWidth,'align':'left'},
    160.     <i nz-icon="" nzType="setting"></i>{'title':'util.lineNumber','width':x_tb.config.table.lineNumberWidth,'align':'left'},
    161.     <i nz-icon="" nzType="setting"></i>{'title':'identity.operation.name'},{'title':'identity.operation.uri'},
    162.     <i nz-icon="" nzType="setting"></i>{'title':'identity.operation.isBase'},{'title':'identity.operation.remark'},
    163.     <i nz-icon="" nzType="setting"></i>{'title':'identity.operation.enabled'},{'title':'util.creationTime'},
    164.     <i nz-icon="" nzType="setting"></i>{'title':'util.lastModificationTime'},{'title':'util.operation'}]">
    165. </x-table-settings>
    复制代码
    观察  标签, 可以发现 [nzCustomColumn]="ts_tb.columns" , 说明确实使用的是 Ng Zorro 官方提供的自定义列功能.
    生成的 html 比较复杂, enable-table-settings 除了开启自定义列外,还会启用拖动列宽等功能.
    前面提到, Util Ui 提供的标签可以压缩 3-10 倍的 html 代码量 , 从这里可以看出, 绝非信口雌黄.
    是由 util-angular 脚本库提供的表格设置组件.
    的 initColumns 属性设置了一个列信息数组, 将列集合传入表格设置组件.
    组件经过系列工序, 输出 Ng Zorro 需要的自定义列信息.
    所以, 无需手工编写任何 ts 脚本代码, 即可完成相关功能.
    可以看到,  TagHelper 不仅可以封装 html 复杂度,甚至能为你生成一些简单的 js 对象.
    要打开表格设置对话框, 需要一个按钮.
    .cshtml 代码如下.
    show-table-settings 用于显示表格设置对话框, 传入表格的引用变量名 tb.
    1. [/code]生成的 html 如下.
    2. [code]    <i nz-icon="" nzType="setting"></i>
    复制代码
    Util UI 的扩展指令和组件具有一些约定的命名.
    表格组件的引用变量名为 tb , 对应的表格设置组件则为 ts_tb .
    表格设置组件提供了一个 show() 函数, 调用该函数即可打开表格设置窗口.

总结

本文分享了 Util 应用框架 UI 最近的突破与进展.
Util 应用框架 UI 最新架构已经稳定, 可以放心使用.
一些开发人员问到使用教程, 嗯, 这是个伤心事, Util 应用框架一直是心传口授模式, 确实没有.
不过 Util 也在考虑突破原有的使用群体, 面向更大的范围传播.
使用教程和文档已经在路上, 欢迎大家使用 , 我们将以更快的速度提供.
欢迎转载何镇汐的技术博客微信扫描二维码支持Util
6.jpeg

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册