目录
看了关于官网的指令层面的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
头疼~