[Angular2+]构造三级Tab目录切换

目录

知识点:

目录结构:

思路:

最外层容器:

一级的内容(outter)

inner同理


看了关于官网的指令层面的tab和动态修改组件,不大适用

就用纯component和input来构造

知识点:

@Input,ngChanges生命钩子,组件。

目录结构:

(组件用cli自动生成即可,svc也是)outter就是那个sidebar,innner就是面板,当然你需要一个最外层最外层的容器,随便你放哪里

思路:

就是组件嵌套+input传值

最外层有个sidebar,sidebar的数据是包含二级条目的所有数据的,给个参考如下图

{}里面还有一级的,不显示了,反正切换的时候带的数据要全部带过去。

先取数据,这里看不懂就算了,每个人取数据的情况不同,我这里返回的数据要自己处理,和tab没有关系

import {Injectable} from '@angular/core';
import {BaseConfig} from '../../settings/base-config';
import {HttpApiProvider} from '../../apis/http-api';

@Injectable({
  providedIn: 'root'
})
export class TabSvcService {

  constructor(
    private http: HttpApiProvider,
    private setting: BaseConfig) {
  }

  public async getPanelData() {
    const TabRes = [];
    let i = 0;
    const res = await this.http.Get(this.setting.editTab_dataUrl);
    for (const key of Object.keys(res)) {// 遍历每一个一级对象
      const TabNavItem = {}; // 构造一级对象的{isselected,标题,子内容,子数据}
      TabNavItem['isSelected'] = i === 0;
      // TabNavItem[key] = res[key];
      TabNavItem['text'] = key;

      const subData = res[key]; // 子数据继续构造
      const SubNavItems = []; // -->一级下的subData
      const InfoTabItems = {};
      let j = 0;
      for (const subKey of Object.keys(subData)) {
        if (j === 0) {
          const subItem = {};
          subItem['nav'] = 'Info';
          subItem['data'] = InfoTabItems;
          subItem['isSelected'] = j === 0;
          SubNavItems.push(subItem);
          j++;
        }
        if (subData[subKey] !== null) { // 除去还有三级数据的条目拼接到Info目录下
          const Item = {};
          Item[subKey] = subData[subKey];
          Object.assign(InfoTabItems, Item);
        } else {
          const subItem = {};
          subItem['nav'] = subKey;
          subItem['isSelected'] = j === 0;
          subItem[subKey] = subData[subKey];
          subItem['data'] = {};
          SubNavItems.push(subItem);
          j++;
        }
        TabNavItem['subData'] = SubNavItems;
      }
      TabRes.push(TabNavItem);
      i++;
    }
    console.log(TabRes);
    return TabRes;
  }

}

 

最外层容器:

这个容器里放outer组件

<div id="edit-panel-wrapper">
  <div class="edit-sidebar">
    <div class="sidebar-item"
         *ngFor="let item of tabItems"
         (click)="SelectItem(item)"
         [class.ItemActive]="item.isSelected">{{item.text}}
    </div>
  </div>
  <div class="edit-outer-panel">
    <app-panel-for-outer-level [subTabItems]="subTabItems"></app-panel-for-outer-level>
  </div>

</div>

这里循环了tabItems来做sidebar,http的方式视情况自己写

 tabItems = []; // 一级条目
  subTabItems = [];

  constructor(private http: HttpApiProvider,
              private tabSvc: TabSvcService) {
   
    // 编辑版侧边栏和panel的nav
    setTimeout(async () => {
      this.tabItems = await this.tabSvc.getPanelData();
      console.log(this.tabItems[0]);
      this.subTabItems = this.tabItems[0]['subData'];
    }, 0);
  }

一级的内容(outter)

input的内容如果取不到或者undefine可能是初始化的问题,所有放进onchanges的钩子里,其他的没什么可说的

import {AfterViewInit, Component, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core';
@Component({
  selector: 'app-panel-for-outer-level',
  templateUrl: './panel-for-outer-level.component.html',
  styleUrls: ['./panel-for-outer-level.component.scss']
})
export class PanelForOuterLevelComponent implements OnInit, AfterViewInit, OnChanges {

  @Input()
  subTabItems;
  panelData;

  constructor() {
  }


  ngOnInit() {
  }

  SelectItem(item) {
    this.subTabItems.forEach(x => {
      x.isSelected = false;
    });
    item.isSelected = true;
    this.panelData = item.data;
  }

  ngAfterViewInit() {
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (this.subTabItems[0] !== undefined) {
      this.panelData = this.subTabItems[0]['data'];
    }

  }
}
<div class="outer-sidebar">
  <div class="outer-sidebar-item"
       *ngFor="let item of subTabItems"
       [class.ItemActive]="item.isSelected"
       (click)="SelectItem(item)">
    {{item.nav}}
  </div>
</div>
<app-panel-for-inner-level [panelData]="panelData"></app-panel-for-inner-level>

inner同理

<div>

  <div class="source-edit-wrapper">


    <div *ngIf="panelData">
      <div class="edit-block-wrapper">
        <div class="edit-block"
             *ngFor="let item of currentData| keyvalue">
          <div class="edit-title"> {{item.key}}</div>
          <div class="edit-data">
            <input type="text"
                   placeholder="{{item.value}}"
                   required="required">
          </div>
        </div>

      </div>


    </div>


  </div>


</div>
import {AfterViewInit, Component, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';

@Component({
  selector: 'app-panel-for-inner-level',
  templateUrl: './panel-for-inner-level.component.html',
  styleUrls: ['./panel-for-inner-level.component.scss']
})
export class PanelForInnerLevelComponent implements OnInit, AfterViewInit, OnChanges {

  @Input()
  panelData;

  currentData;

  constructor() {
  }

  ngAfterViewInit() {

  }

  ngOnInit() {
  }

  ngOnChanges(changes: SimpleChanges): void {
    this.currentData = this.panelData;
  }


}

然后我大部分时间用在处理数据封装上了,但是tab的切换原理其实很简单

难的是我以后怎么回传t.t

头疼~

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值