Tabs

api

  • nzSelectChange: EventEmitter<{nzSelectedIndex: number,tab: NzTabComponent}>
  • nzSelect: EventEmitter,点击另外一个触发
  • nzClick: EventEmitter,点击当前也会触发 ```typescript import { Component, OnInit } from ‘@angular/core’;

@Component({ selector: ‘nz-demo-tabs-slide’, template: <nz-radio-group [(ngModel)]="nzTabPosition"> <label nz-radio-button [nzValue]="'top'">Horizontal</label> <label nz-radio-button [nzValue]="'left'">Vertical</label> </nz-radio-group> <nz-input-number style="float:right;" [nzMin]="0" [nzMax]="10" [(ngModel)]="selectedIndex"></nz-input-number> <nz-tabset style="height:220px;" [nzTabPosition]="nzTabPosition" [(nzSelectedIndex)]="selectedIndex" (nzSelectChange)="log([$event])" > <nz-tab *ngFor="let tab of tabs" [nzTitle]="tab.name" (nzSelect)="log(['select', tab])" (nzClick)="log(['click', tab])" (nzDeselect)="log(['deselect', tab])" > {{ tab.content }} </nz-tab> </nz-tabset> })

export class NzDemoTabsSlideComponent implements OnInit { tabs: Array<{ name: string; content: string }> = []; nzTabPosition = ‘top’; selectedIndex = 0;

/ tslint:disable-next-line:no-any / log(args: any[]): void { console.log(args); }

ngOnInit(): void { for (let i = 0; i < 11; i++) { this.tabs.push({ name: Tab ${i}, content: Content of tab ${i} }); } } }

  1. <a name="Nw5hm"></a>
  2. ## tab路由联动模式
  3. <a name="FrOsr"></a>
  4. ### 两种方式:
  5. - 1. 直接路径匹配
  6. - 2. queryParams匹配
  7. ```typescript
  8. import { Component } from '@angular/core';
  9. @Component({
  10. selector: 'nz-demo-tabs-link-router',
  11. template: `
  12. <nz-tabset nzLinkRouter>
  13. <nz-tab>
  14. <a nz-tab-link [routerLink]="['.']" [queryParams]="{ tab: 'one' }" queryParamsHandling="merge">Default</a>
  15. Default.
  16. </nz-tab>
  17. <nz-tab>
  18. <a nz-tab-link [routerLink]="['.']" [queryParams]="{ tab: 'two' }" queryParamsHandling="merge">Two</a>
  19. Two.
  20. </nz-tab>
  21. <nz-tab>
  22. <a nz-tab-link [routerLink]="['.']" [queryParams]="{ tab: 'three' }" queryParamsHandling="merge">Three</a>
  23. Three.
  24. </nz-tab>
  25. <nz-tab>
  26. <a nz-tab-link [routerLink]="['.']" [queryParams]="{ tab: 'four' }" queryParamsHandling="merge">Four</a>
  27. Four.
  28. </nz-tab>
  29. </nz-tabset>
  30. `
  31. })
  32. export class NzDemoTabsLinkRouterComponent {}

严格匹配

  1. <!-- BUG: 此ng-zorro版本的路由联动模式存在变更检测的bug -->
  2. <!-- 非严格模式匹配,切换二级标签时tab不变化 -->
  3. <nz-tabset nzLinkRouter [nzLinkExact]="false">
  4. <nz-tab>
  5. <a nz-tab-link [routerLink]="['./standard-category']" queryParamsHandling="merge">类目</a>
  6. </nz-tab>
  7. <nz-tab>
  8. <a nz-tab-link [routerLink]="['./standard-color']" queryParamsHandling="merge">颜色</a>
  9. </nz-tab>
  10. <nz-tab>
  11. <a nz-tab-link [routerLink]="['./field-classify']" queryParamsHandling="merge">字段分类</a>
  12. </nz-tab>
  13. </nz-tabset>
  14. <router-outlet></router-outlet>

Anchor

注意target容器

Modal

服务方式创建组件modal

nzContent , nzComponentParams

  1. createComponentModal(): void {
  2. const modal = this.modalService.create({
  3. nzTitle: 'Modal Title',
  4. nzContent: NzModalCustomComponent,
  5. nzComponentParams: {
  6. title: 'title in component',
  7. subtitle: 'component sub title,will be changed after 2 sec'
  8. },
  9. nzFooter: [
  10. {
  11. label: 'change component title from outside',
  12. onClick: componentInstance => {
  13. componentInstance!.title = 'title in inner component is changed';
  14. }
  15. }
  16. ]
  17. });
  1. // 外层组件中
  2. modal.afterOpen.subscribe(() => console.log('[afterOpen] emitted!'));
  3. // Return a result when closed
  4. modal.afterClose.subscribe(result => console.log('[afterClose] The result is:', result));
  5. // delay until modal instance created
  6. setTimeout(() => {
  7. const instance = modal.getContentComponent();
  8. instance.subtitle = 'sub title is changed';
  9. }, 2000);

modal组件中依赖注入NzModalRef

  1. export class NzModalCustomComponent {
  2. @Input() title: string;
  3. @Input() subtitle: string;
  4. constructor(private modal: NzModalRef) {}
  5. destroyModal(): void {
  6. this.modal.destroy({ data: 'this the result data' });
  7. }
  8. }

template服务方式创建,及最简单的使用modal弹窗(无任何按钮,例如查看大图)

重点:

  1. nzFooter: null,
  2. 版本9以上可通过nzComponentParams传入template的上下文,9以下只能绑定成员变量

    1. <ng-template #tplSimilarPicView>
    2. <div class="show-img">
    3. <img [src]="showImg" alt="图片打开失败">
    4. </div>
    5. </ng-template>
    1. export class SimilarSearch {
    2. @ViewChild('tplSimilarPicView', { static: true }) tplSimilarPicView: TemplateRef<{}>;
    3. onProductPicClick(selectProduct: SimlarSearchProduct) {
    4. this.selectProduct(selectProduct);
    5. // this.showProductPortrait(selectProduct);
    6. /** 7.15版本点击大图只展示一张放大图, 不调接口获取封面图的任何信息 */
    7. this.modalService.create({
    8. nzContent: this.tplSimilarPicView,
    9. nzFooter: null,
    10. nzClosable: false
    11. });
    12. }

    案例/字段重构

    1. const modal = this.modalService.create({
    2. nzTitle: '提交商品',
    3. nzContent: SubmitChoose,
    4. nzComponentParams: {},
    5. nzOnOk: (comp) => {
    6. if (comp.isPartialSubmit) {
    7. this.popupPartialSave();
    8. } else {
    9. this.totalSubmit();
    10. }
    11. }
    12. });

    upload

    uploadFiles是每次上传的(数组时指,可能鼠标多选了几个)

    1. filters: UploadFilter[] = [
    2. {
    3. name: 'type',
    4. fn: (uploadFiles: UploadFile[]) => {
    5. return uploadFiles;
    6. }
    7. }
    8. ];

    fileList是当前所有已上传的。 这里列表只显示最新的这个。

    1. onUploadChange($event) {
    2. this.fileList = $event.fileList.slice(-1); // 注意不能用splice,会破坏$event.fileList
    3. }

Tree

  1. 什么是受控组件? 目前看来是没有使用ViewChild
  2. isHalfChecked 不会改变checkbox样式
  3. nzCheckStrictly checkable 状态下节点选择完全受控(父子节点选中状态不再关联),即都是单个单个的选中,而不是所有子节点都选择的话则就选择父节点。不太好用,以下是手动控制选择子节点、父节点。

    1. class Tree {
    2. /** 点选子节点 */
    3. checkNodeChildren(treeNode: NzTreeNode) {
    4. const children = treeNode.children;
    5. if (children && children.length) {
    6. children.forEach(child => {
    7. child.isChecked = treeNode.isChecked;
    8. this.checkNodeChildren(child);
    9. });
    10. }
    11. }
    12. /** 点选父节点 */
    13. checkParent(treeNode: NzTreeNode) {
    14. const parent = treeNode.parentNode;
    15. if (parent) {
    16. parent.isChecked = this.isAllNodesChecked(parent.children);
    17. parent.isHalfChecked = this.isIndeterminate(parent.children);
    18. this.checkParent(parent);
    19. }
    20. }
    21. private isAllNodesChecked(nodes: NzTreeNode[]) {
    22. return nodes.every((node: NzTreeNode) => node.isChecked);
    23. }
    24. private isIndeterminate(nodes: NzTreeNode[]) {
    25. return nodes.some((child: NzTreeNode) => child.isChecked) && !this.isAllNodesChecked(nodes);
    26. }
    27. }
  4. 若要选择父节点时也同时选择其下的所有子节点,如下:

    1. getCheckedNodes(): NzTreeNode[] {
    2. const checkedNodes = this.categoryTree.getCheckedNodeList();
    3. return checkedNodes.concat(flatten(checkedNodes.map(node => node.children || [])));
    4. }
  5. [nzBlockNode]属性

节点(非叶子)为display: block,占据一行