功能描述:从下拉框"Service(服务)","ServiceInstances (服务实例)","Endpoints(端点)"三个数据源获取数据,然后在下面的二级复选框列表展示,最终获得用户选取的数据.
(1).ServiceInstances (服务实例)
和 Endpoints(端点)
是用 Service(服务)
的key
查出来的.
(2).所以Service(服务)
只有一级数据,ServiceInstances (服务实例)
和 Endpoints(端点)
有二级数据.
问题:
1.拼接dataEndPoints数据格式是否合理
2.如何实现2级动态绑定取值
在线demo:
https://codesandbox.io/s/kind...
一.数据描述:
1.Service(服务)
返回数据:
{
"data": {
"services": [
{
"key": "aXN0aW86OmlzdGlvZA==.1",
"label": "istio::istiod",
"group": "istio"
},
{
"key": "aXN0aW86OmlzdGlvLWVncmVzc2dhdGV3YXk=.1",
"label": "istio::istio-egressgateway",
"group": "istio"
}]
}
}
2.ServiceInstances (服务实例)
返回数据,[查询参数需要Service(服务)的key
]:
{
"data": {
"getServiceInstances": [
{
"key": "aXN0aW8tZHA6OmN1cnJlbmN5c2VydmljZQ==.1_Y3VycmVuY3lzZXJ2aWNlLTVkNWQ0OTY5ODQtdGQ1YzI=",
"label": "currencyservice-5d5d496984-td5c2",
"language": "UNKNOWN",
"attributes": []
}
]
}
}
3.Endpoints(端点)
返回数据[查询参数需要Service(服务)的key
]:
{
"data": {
"getEndpoints": [
{
"key": "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL1NoaXBPcmRlcg==",
"label": "POST:/hipstershop.ShippingService/ShipOrder"
},
{
"key": "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL0dldFF1b3Rl",
"label": "POST:/hipstershop.ShippingService/GetQuote"
}
]
}
}
二.HTML代码部分:
<el-container>
<el-main>
<el-form ref="form" label-width="100px" style="margin: 0 0 100px 0">
</el-form>
<el-row>
<el-col :span="3">
<el-button type="success" @click="dialogFormIndividualRulesVisible = true">新增单独配置</el-button>
</el-col>
<!-- 新增单独配置弹出Form -->
<el-dialog
title="新增单独配置"
:visible.sync="dialogFormIndividualRulesVisible"
width="80%"
class="titleH1"
>
<el-form
:model="formIndividualData"
ref="formIndividualData"
:rules="formIndividualRules"
>
<label for class="titleH2">关联资源</label>
<el-form-item label="资源项" prop="resources" :label-width="formLabelWidth">
<el-select
v-model="formIndividualData.resources.label"
@change="getSkywalkingResourcesData"
placeholder="请选择资源项"
>
<el-option
v-for="item in formIndividualData.resources"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<label for class="titleH2">告警对象</label>
<el-form-item label="选择服务" :label-width="formLabelWidth">
<div style="display: flex;">
<el-table
ref="multipleTable"
:data="tableDataAlarmObject"
tooltip-effect="dark"
style="width: 40%"
border
height="200"
:header-cell-style="{
'background-color': '#add5fd',
'color': 'rgb(255, 255, 255)',
}"
@selection-change="handleSelectionChange1"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="label" label="服务名称">
<template slot="header" slot-scope="scope">
<el-input
@input="searchChange1"
v-model="search"
size="mini"
placeholder="输入关键字搜索"
/>
</template>
</el-table-column>
</el-table>
<el-table
ref="multipleTable2"
:data="tableDataChildAlarmObject"
tooltip-effect="dark"
style="width: 40%"
border
height="200"
:header-cell-style="{
'background-color': '#add5fd',
'color': 'rgb(255, 255, 255)',
}"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="label" label="服务名称"></el-table-column>
</el-table>
</div>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormIndividualRulesVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogIndividualRules(formIndividualData)">确 定</el-button>
</div>
</el-dialog>
</el-row>
</el-main>
</el-container>
三.TS部分:
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
type AlarmObjectForm = {
checked?: boolean;
};
@Component({
components: {
}
})
export default class ConfigurationList extends Vue {
private dialogFormIndividualRulesVisible: boolean = false;
private dialogFormCompositeRulesVisible: boolean = false;
private formIndividualData: any = {
resources: [
{ label: "服务", value: "graphql/1" },
{ label: "服务实例", value: "/graphql/2" },
{ label: "端点", value: "/graphql/3" }
],
ruleName: "",
norm: [
{ label: "p95", value: "p95" },
{ label: "p75", value: "p75" },
{ label: "p55", value: "p55" }
],
rule: "",
operation: "",
num1: 0,
checked: false,
num2: 0,
num3: 0
};
private formLabelWidth: string = "120px";
private num: number = 1;
private checked: boolean = false;
private search: string = "";
private searchFlag: boolean = false;
private tableDataAlarmObject: Array<AlarmObjectForm> = [];
private tableDataChildAlarmObject: Array<AlarmObjectForm> = [];
// Service 下的 EndPoints 合并数据(格式是否合理?)
private dataEndPoints: Array<any> = [
{
key: "aXN0aW86OmNhcnRzZXJ2aWNl.1",
label: "istio::cartservice",
group: "istio",
getEndpoints: [
{
key:
"aXN0aW86OmNhcnRzZXJ2aWNl.1_UE9TVDovaGlwc3RlcnNob3AuQ2FydFNlcnZpY2UvR2V0Q2FydA==",
label: "POST:/hipstershop.CartService/GetCart"
},
{
key:
"aXN0aW86OmNhcnRzZXJ2aWNl.1_UE9TVDovaGlwc3RlcnNob3AuQ2FydFNlcnZpY2UvRW1wdHlDYXJ0",
label: "POST:/hipstershop.CartService/EmptyCart"
}
]
},
{
key: "aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1",
label: "istio-dp::ratings",
group: "istio-dp",
getEndpoints: [
{
key:
"aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL1NoaXBPcmRlcg==",
label: "POST:/hipstershop.ShippingService/ShipOrder"
},
{
key:
"aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL0dldFF1b3Rl",
label: "POST:/hipstershop.ShippingService/GetQuote"
}
]
},
{
key: "aXN0aW8tZHA6OnJlY29tbWVuZGF0aW9uc2VydmljZQ==.1",
label: "istio-dp::recommendationservice",
group: "istio-dp",
getEndpoints: [
{
key:
"aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL1NoaXBPcmRlcg==",
label: "POST:/hipstershop.ShippingService/ShipOrder"
},
{
key:
"aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL0dldFF1b3Rl",
label: "POST:/hipstershop.ShippingService/GetQuote"
}
]
},
{
key: "aXN0aW8tZHA6OnByb2R1Y3RwYWdl.1",
label: "istio-dp::productpage",
group: "istio-dp",
getEndpoints: [
{
key:
"aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL1NoaXBPcmRlcg==",
label: "POST:/hipstershop.ShippingService/ShipOrder"
},
{
key:
"aXN0aW86OnNoaXBwaW5nc2VydmljZQ==.1_UE9TVDovaGlwc3RlcnNob3AuU2hpcHBpbmdTZXJ2aWNlL0dldFF1b3Rl",
label: "POST:/hipstershop.ShippingService/GetQuote"
}
]
}
];
// Service 下的 ServiceInstances 合并数据
private dataServiceInstances: Array<any> = [];
private multipleSelection: Array<any> = [];
private skyWalkingUrl: string = "";
private temEndPoints: Array<any> = [];
private addButtonHide: boolean = true;
handleChange(value: any) {
console.log(value);
}
created() {
this.tableDataAlarmObject = [...this.dataEndPoints]; // 保持源数组的独立性,
console.log(this.tableDataAlarmObject);
}
/**
* 新建告警配置-选择服务复选框
*/
handleSelectionChange1(val: any) {
if (this.searchFlag) {
// 手动选中过程中不予响应
return;
}
this.tableDataAlarmObject.forEach(item => {
item.checked = false;
});
val.forEach((row: any) => {
row.checked = true;
});
console.log("val-->", val);
let arr: Array<any> = [];
for (let i in val) {
const getEndpoints = (val[i] as any).getEndpoints.map((item: any) => {
item.p_key = (val[i] as any).key;
return item;
});
this.tableDataChildAlarmObject = arr.concat(getEndpoints);
}
}
/**
* 新建告警配置-选择服务-复选框搜索
*/
searchChange1() {
var arr = this.dataEndPoints.filter(
data =>
!this.search ||
data.label.toLowerCase().includes(this.search.toLowerCase())
);
this.tableDataAlarmObject.splice(0, this.tableDataAlarmObject.length);
Array.prototype.push.apply(this.tableDataAlarmObject, arr); // 不改变tableDataAlarmObject 数组的引用地址。保持其响应式。
this.$nextTick(() => {
this.searchFlag = true; // 手动选中前 禁止多选事件响应
this.tableDataAlarmObject.forEach(item => {
if (item.checked)
(this.$refs.multipleTable as any).toggleRowSelection(item, true);
});
this.searchFlag = false; // 放开多选事件响应
});
}
/**
* 获取新增单独规则关联资源项的数据
*/
getSkywalkingResourcesData(url: string) {
console.log(url);
}
dialogIndividualRules(formIndividualData: any) {
let individualData: any = this.$refs.formIndividualData;
individualData.validate((valid: any) => {
if (valid) {
alert("submit!");
this.dialogFormIndividualRulesVisible = false;
} else {
console.log("error submit!!");
return false;
}
});
}
}
</script>