as3中如何向Alert.show的回调函数传递参数

本文介绍如何在ActionScript 3中使用Alert控件实现弹窗效果,并通过示例展示如何在回调函数中传递多个参数以实现更复杂的业务逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们知道,as3的Alert控件可以实现弹出信息框的效果(有点类似Javascript的alert函数),通常调用Alert.show方法来实现,当我们要完成一个确认操作(比如删除显示列表中的某一条目)时,通常编写如下代码:

Alert.show("是否删除该条目?","确认删除",Alert.YES|Alert.NO,this,callbackFunction);

//代码执行时将弹出一个对话框,并显示YES和NO两个按钮,callbackFunction 是点击按钮后执行的回调函数

private function callbackFunction(event:CloseEvent):void{
        if(Alert.YES == event.detail){
            //当点击YES时的操作
        }else{
            //当点击NO时的操作
        }
}


在上面的示例代码中,callbackFunction只包含event一个参数,如果我们需要传递更多的参数,貌似不太好办了,实际上,我们可以通过在callbackFunction函数外再封装一层函数的方法来实现。

比如我们要在callbackFunction函数中传递一个字符串'id is:'和一个整型15,实现方法请参见如下代码:

var str:String = 'id is:';

var num:int = 15;

Alert.show("是否删除该条目?","确认删除",Alert.YES|Alert.NO,this,function(e:CloseEvent):void{callbackFunction(e,str,num)});

private function callbackFunction(event:CloseEvent,str:String,num:int):void{
        if(Alert.YES == event.detail){
            //当点击YES时的操作
            Alert.show(str+num.toString(),"您点击了YES按钮");
        }else{
            //当点击NO时的操作
        }
 }

运行上面的示例代码,当您在弹出的信息框上点击YES按钮后,将弹出一个标题为"您点击了YES按钮",内容为"id is 15"的信息框,而点击NO按钮则没有任何操作。这样,既可以捕获CloseEvent事件,又可以将我们业务逻辑中变量的值带到回调函数中,当我们要实现删除某个列表项的功能时,就变得很方便了。


<template> <div class="vote-container"> <!-- 消息提示 --> <div v-if="showAlert" :class="[&#39;alert&#39;, alertType]"> {{ alertMessage }} </div> <!-- 投票人信息 --> <div class="voter-info" v-if="voterName && voterIdCard"> <p>投票人:{{ voterName }}</p> <p>身份证:{{ formattedIdCard }}</p> </div> <!-- 投票统计信息 --> <div class="stats"> <div class="stat"> <h3>经理投票</h3> <div class="progress"> <div class="progress-bar" :style="{ width: (votes[17] / 5) * 100 + &#39;%&#39; }"></div> </div> <p>{{ votes[17] }} / 5</p> </div> <div class="stat"> <h3>厂长投票</h3> <div class="progress"> <div class="progress-bar" :style="{ width: (votes[18] / 5) * 100 + &#39;%&#39; }"></div> </div> <p>{{ votes[18] }} / 5</p> </div> <div class="stat"> <h3>副厂长投票</h3> <div class="progress"> <div class="progress-bar" :style="{ width: (votes[19] / 15) * 100 + &#39;%&#39; }"></div> </div> <p>{{ votes[19] }} / 15</p> </div> <div class="stat"> <h3>总票数</h3> <div class="progress"> <div class="progress-bar" :style="{ width: (totalVotes / 25) * 100 + &#39;%&#39; }"></div> </div> <p>{{ totalVotes }} / 25</p> </div> </div> <!-- 被投票人列表 --> <div class="voters-grid"> <div v-for="voter in voters" :key="voter.id" class="voter-card"> <h4>{{ voter.name }}</h4> <p class="voter-id">ID: {{ voter.id }}</p> <div class="vote-options"> <button @click="castVote(voter, 17)" :disabled="!canVote(voter, 17)" :class="{ &#39;selected&#39;: voter.vote === 17, &#39;disabled&#39;: !canVote(voter, 17) }" > 经理 </button> <button @click="castVote(voter, 18)" :disabled="!canVote(voter, 18)" :class="{ &#39;selected&#39;: voter.vote === 18, &#39;disabled&#39;: !canVote(voter, 18) }" > 厂长 </button> <button @click="castVote(voter, 19)" :disabled="!canVote(voter, 19)" :class="{ &#39;selected&#39;: voter.vote === 19, &#39;disabled&#39;: !canVote(voter, 19) }" > 副厂长 </button> </div> </div> </div> <!-- 操作按钮 --> <div class="action-buttons"> <button @click="submitVotes" :disabled="!hasSelectedCandidates || isSubmitting">提交投票</button> <button @click="resetVotes" :disabled="isSubmitting">重置投票</button> </div> </div> </template> <script setup> import { ref, reactive, computed } from &#39;vue&#39;; import { useRoute, useRouter} from &#39;vue-router&#39;; import { onMounted } from &#39;vue&#39;; const route = useRoute(); const router = useRouter() const voters = ref([]); //候选人 // 使用props接收参数 const props = defineProps({ queryParams: { type: Object, default: () => ({}) } }) // 使用计算属性 const activeSurvey = ref({ surveyId: route.params.surveyId,//调查令 qydcl: route.params.qydcl, dclx: route.query.dclx, tffs: route.query.tffs, bt: route.query.bt }); onMounted(async() => { // 确保路由完全解析完成 await router.isReady() // console.log(&#39;当前路由对象:&#39;, route) // console.log(&#39;路径参数:&#39;, route.params) // 获取params参数 // console.log(&#39;查询参数:&#39;, route.query) // 获取query参数 }); // 添加消息提示状态 const alertMessage = ref(&#39;&#39;); const showAlert = ref(false); const alertType = ref(&#39;&#39;); // &#39;success&#39; 或 &#39;error&#39; // 安全序列化函数 function safeStringify(obj) { const seen = new WeakSet(); return JSON.stringify(obj, (key, value) => { if (typeof value === "object" && value !== null) { if (seen.has(value)) { // 检测到循环引用,返回占位符或跳过 return "[Circular Reference Removed]"; } seen.add(value); } return value; }); } // onMounted生命周期钩子 onMounted(async () => { // 从sessionStorage获取投票人信息并立即清除 const voterInfo = sessionStorage.getItem(&#39;voterInfo&#39;); if (voterInfo) { const { name, idCard } = JSON.parse(voterInfo); voterName.value = name; voterIdCard.value = idCard; sessionStorage.removeItem(&#39;voterInfo&#39;); } // 获取投票详情 const route = useRoute(); // 加载候选人数据 voters.value = await fetchCandidates(); }); // 添加用于存储投票人信息的变量 const voterName = ref(&#39;&#39;); const voterIdCard = ref(&#39;&#39;); // 格式化身份证显示(安全脱敏) const formattedIdCard = computed(() => { if (!voterIdCard.value) return &#39;&#39;; // 显示前6位和后4位,中间用*代替 return voterIdCard.value.substring(0, 6) + &#39;******&#39; + voterIdCard.value.substring(voterIdCard.value.length - 4); }); onMounted(() => { // 从sessionStorage获取数据并立即清除 const voterInfo = sessionStorage.getItem(&#39;voterInfo&#39;); if (voterInfo) { const { name, idCard } = JSON.parse(voterInfo); voterName.value = name; voterIdCard.value = idCard; // 关键:立即清除存储防止数据残留 sessionStorage.removeItem(&#39;voterInfo&#39;); } }); //获取候选人明细 const fetchCandidates = async () => { try { const response = await fetch(&#39;/api/wechat/getInvestigate&#39;, { method: &#39;POST&#39;, body: JSON.stringify({ id: &#39;9&#39;, dcl: &#39;123&#39; }) }); // console.log(&#39;API响应:&#39;, response); const result = await response.json(); if (!result || !result.root) throw new Error(&#39;无效API响应&#39;); // 提取候选人数据 const candidateArray = []; let idCounter = 1; // 自增计数器,名称序号 result.root.forEach(rootItem => { if (!rootItem.childEntList) return; rootItem.childEntList.forEach(candidate => { if (!candidate.dcbt || !candidate.dcxbt) return; candidateArray.push({ name: candidate.dcxbt, vote: null, id:idCounter++, tmlx: candidate.tmlx, // 投票类型 mainId: candidate.mainId, // 主ID dcbt: candidate.dcbt, // 投票标题 }); }); }); // console.log(&#39;候选人数据:&#39;, candidateArray); return candidateArray; } catch (error) { console.error(&#39;获取候选人失败:&#39;, error); return []; // 返回空数组保持安全 } }; // 新增计算属性 - 获取已选择的候选人 const selectedCandidates = computed(() => { return voters.value .filter(v => v.vote) // 只过滤已投票的 .map(v => ({ mainId: v.mainId, // 候选人原始ID voteType: v.vote, // 投票类型 voteValue: v.vote, name: v.name, // 候选人姓名 tmlx: v.tmlx, // 原始类型 dcbt: v.dcbt // 投票标题 })); }); // 检查是否有选择的候选人 const hasSelectedCandidates = computed(() => { return selectedCandidates.value.length > 0; }); //获取并保存第一个候选人的mainId const mainIdToSubmit = ref(null); const firstCandidateMainId = computed(() => { return selectedCandidates.value[0]?.mainId || null; }); // 投票统计 const votes = reactive({ 17: 0, 18: 0, 19: 0 }); // 计算总票数 const totalVotes = computed(() => { return votes[17] + votes[18] + votes[19]; }); // 检查投票资格 const canVote = (voter, type) => { // 当前投票类型限额配置 const limits = { 17: 5, 18: 5, 19: 15 }; // 情况1:用户取消当前选择的类型(总是允许) if (voter.vote === type) return true; // 情况2:用户切换投票类型 if (voter.vote) { // 检查新类型是否达到限额 if (votes[type] >= limits[type]) return false; } // 情况3:用户首次投票 else { // 检查新类型是否达到限额和总票数 if (votes[type] >= limits[type] || totalVotes.value >= 25) return false; } return true; }; // 投票方法 const castVote = (voter, voteValue) => { // 如果已投票且点击相同类型,取消投票 if (voter.vote === voteValue) { voter.vote = null; votes[voteValue]--; return; } // 如果之前有投票,先取消 if (voter.vote !== null) { votes[voter.vote]--; } // 投新票 voter.vote = voteValue; votes[voteValue]++; }; //投票人信息 // 添加投票人信息数据模型 const voterInfo = reactive({ name: &#39;&#39;, idNumber: &#39;&#39; }); // 提交投票 // 防止重复提交 const isSubmitting = ref(false); // 提交投票到API const submitVotes = async () => { // console.log("dclx", activeSurvey.value.dclx); // 添加防御性检查 if (!hasSelectedCandidates.value) { showMessage(&#39;请先选择候选人&#39;, &#39;error&#39;); return; } // 防止重复提交 if (isSubmitting.value) return; isSubmitting.value = true; // 设置mainId值 mainIdToSubmit.value = firstCandidateMainId.value; try { const mainData = [ { fieldName: "bt", fieldValue: activeSurvey.value.bt }, { fieldName: "tprxm", fieldValue: voterName.value }, { fieldName: "tprsfz", fieldValue: voterIdCard.value }, { fieldName: "mb", fieldValue: mainIdToSubmit.value }, { fieldName: "dclx", fieldValue: activeSurvey.value.dclx }, { fieldName: "tffs", fieldValue: activeSurvey.value.tffs } ]; const workflowRequestTableRecords = selectedCandidates.value.map(candidate => ({ workflowRequestTableFields: [ { fieldName: "dcbt", fieldValue: candidate.dcbt }, { fieldName: "tmlx", fieldValue: candidate.tmlx }, { fieldName: "dcxx", fieldValue: candidate.vote === &#39;A&#39; ? 17 : candidate.vote === &#39;B&#39; ? 18 : 19 } ] })); // console.log(&#39;提交数据:&#39;, { // mainData, // workflowRequestTableRecords // }); const requestBody = { requestName: activeSurvey.value.bt, // 投票标题 workflowId: 118, // 固定工作流ID mainData, workflowRequestTableRecords }; // 发送POST请求 const response = await fetch(&#39;/api/wechat/addInvestigateWorkflow1&#39;, { method: &#39;POST&#39;, headers: { &#39;Content-Type&#39;: &#39;application/json&#39; }, body: safeStringify(requestBody)// 使用安全序列化,避免重复引用 }); const result = await response.json(); // 根据 api_status 判断 if (result.api_status === true) { // 成功处理 const successMsg = result.msg || &#39;投票提交成功!&#39;; showMessage(&#39;投票提交成功!&#39;, &#39;success&#39;); // 存储已投票标识 localStorage.setItem(&#39;voted_&#39; + voterIdCard.value, &#39;true&#39;); } else { // 处理错误情况 if (result.msg === &#39;你已提交或不满足提交条件&#39;) { showMessage(result.msg, &#39;error&#39;); // 特殊处理:用户已投票,存储标识防止重复提交 localStorage.setItem(&#39;voted_&#39; + voterIdCard.value, &#39;true&#39;); } else { // 其他错误情况 const errorMsg = result.msg ? `提交失败: ${result.msg}` : &#39;未知错误,请稍后重试&#39;; showMessage(errorMsg, &#39;error&#39;); } } } catch (error) { console.error(&#39;网络请求失败:&#39;, error); showMessage(&#39;网络错误,请检查连接后重试&#39;, &#39;error&#39;); } finally { isSubmitting.value = false; } }; // 重置投票 const resetVotes = () => { if (confirm(&#39;确定要重置所有投票吗?&#39;)) { voters.value.forEach(voter => { voter.vote = null; }); votes.A = 0; votes.B = 0; votes.C = 0; voterInfo.name = &#39;&#39;; voterInfo.idNumber = &#39;&#39;; } }; //后台响应信息showMessage const showMessage = (message, type = &#39;error&#39;) => { // 更新消息提示状态 alertMessage.value = message; showAlert.value = true; alertType.value = type; // 错误提示停留3秒,成功提示停留2秒 const timeout = type === &#39;error&#39; ? 3000 : 2000; setTimeout(() => { showAlert.value = false; }, timeout); }; </script> <style scoped> /* 移动端垂直布局 */ @media (max-width: 480px) { .input-group { flex-direction: column; } } /* 平板/桌面端水平布局 */ @media (min-width: 768px) { .input-group { flex-direction: row; } } /* 消息提示样式 */ .alert { padding: 15px; margin-bottom: 20px; border-radius: 4px; text-align: center; position: fixed; top: 20px; left: 50%; transform: translateX(-50%); z-index: 1000; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); min-width: 300px; opacity: 0.95; } .alert.error { background-color: #ffebee; color: #b71c1c; border: 1px solid #ffcdd2; } .alert.success { background-color: #e8f5e9; color: #1b5e20; border: 1px solid #c8e6c9; } .vote-container { max-width: 1200px; margin: 0 auto; padding: 20px; } .stats { display: flex; justify-content: space-between; margin-bottom: 30px; background: #f5f7fa; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); } .stat { flex: 1; text-align: center; padding: 0 15px; } .progress { height: 20px; background: #e0e0e0; border-radius: 10px; margin: 10px 0; overflow: hidden; } .progress-bar { height: 100%; background: #3498db; transition: width 0.3s; } .voters-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 20px; } .voter-card { background: white; border-radius: 8px; padding: 15px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); transition: transform 0.2s; } .voter-card:hover { transform: translateY(-5px); } .voter-id { color: #777; font-size: 0.9rem; margin-bottom: 15px; } .vote-options { display: flex; justify-content: space-between; } .vote-options button { flex: 1; margin: 0 5px; padding: 8px 0; border: none; border-radius: 4px; cursor: pointer; transition: all 0.2s; } .vote-options button:not(.selected):hover { opacity: 0.9; transform: scale(1.05); } .vote-options button:first-child { background: #ff6b6b; color: white; } .vote-options button:nth-child(2) { background: #4ecdc4; color: white; } .vote-options button:last-child { background: #ffd166; color: white; } .selected { border: 2px solid #2c3e50 !important; font-weight: bold; box-shadow: 0 0 2 rgba(61, 60, 60, 0.5); } .disabled { opacity: 0.5 !important; cursor: not-allowed !important; } .action-buttons { margin-top: 30px; display: flex; justify-content: center; gap: 20px; } .action-buttons button { padding: 12px 30px; border: none; border-radius: 6px; cursor: pointer; font-size: 1rem; font-weight: 600; transition: all 0.2s; } .action-buttons button:first-child { background: #3498db; color: white; } .action-buttons button:first-child:disabled { background: #bdc3c7; cursor: not-allowed; } .action-buttons button:last-child { background: #e74c3c; color: white; } .action-buttons button:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); } </style>浏览器报错:Uncaught (in promise) TypeError: _ctx.canVote is not a function at eval (VM10454 Vote.vue:88:23) at renderList (runtime-core.esm-bundler.js:2904:1) at Proxy.render (VM10454 Vote.vue:82:552) at renderComponentRoot (runtime-core.esm-bundler.js:6501:1) at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js:5397:1) at ReactiveEffect.run (reactivity.esm-bundler.js:225:1) at ReactiveEffect.runIfDirty (reactivity.esm-bundler.js:263:1) at callWithErrorHandling (runtime-core.esm-bundler.js:199:1) at flushJobs (runtime-core.esm-bundler.js:408:1) eval @ VM10454 Vote.vue:88 renderList @ runtime-core.esm-bundler.js:2904 render @ VM10454 Vote.vue:82 renderComponentRoot @ runtime-core.esm-bundler.js:6501 componentUpdateFn @ runtime-core.esm-bundler.js:5397 run @ reactivity.esm-bundler.js:225 runIfDirty @ reactivity.esm-bundler.js:263 callWithErrorHandling @ runtime-core.esm-bundler.js:199 flushJobs @ runtime-core.esm-bundler.js:408 Promise.then queueFlush @ runtime-core.esm-bundler.js:322 queueJob @ runtime-core.esm-bundler.js:317 effect.scheduler @ runtime-core.esm-bundler.js:5448 trigger @ reactivity.esm-bundler.js:253 endBatch @ reactivity.esm-bundler.js:311 notify @ reactivity.esm-bundler.js:597 trigger @ reactivity.esm-bundler.js:571 set value @ reactivity.esm-bundler.js:1448 eval @ VM10456 Vote.vue:94 await in eval eval @ runtime-core.esm-bundler.js:2815 callWithErrorHandling @ runtime-core.esm-bundler.js:199 callWithAsyncErrorHandling @ runtime-core.esm-bundler.js:206 hook.__weh.hook.__weh @ runtime-core.esm-bundler.js:2795 flushPostFlushCbs @ runtime-core.esm-bundler.js:385 flushJobs @ runtime-core.esm-bundler.js:427 Promise.then queueFlush @ runtime-core.esm-bundler.js:322 queueJob @ runtime-core.esm-bundler.js:317 reload @ runtime-core.esm-bundler.js:527 eval @ runtime-core.esm-bundler.js:561 eval @ Vote.vue:15 ./src/views/Vote.vue @ about.js:1355 __webpack_require__ @ app.js:308 _requireSelf @ app.js:599 apply @ app.js:1335 (匿名) @ app.js:839 internalApply @ app.js:837 (匿名) @ app.js:775 waitForBlockingPromises @ app.js:730 (匿名) @ app.js:773 Promise.then (匿名) @ app.js:772 Promise.then (匿名) @ app.js:753 Promise.then hotCheck @ app.js:744 check @ dev-server.js:15 eval @ dev-server.js:69 emit @ events.js:153 reloadApp @ reloadApp.js:38 ok @ index.js:227 eval @ socket.js:62 client.onmessage @ WebSocketClient.js:45
06-12
import React, { useState, useEffect, useCallback, useMemo } from "react"; import { JsonForms } from "@jsonforms/react"; import { materialCells, materialRenderers } from &#39;@jsonforms/material-renderers&#39;; import EnumSelectRenderer, { EnumSelectRendererTester } from &#39;../../renderer/EnumSelectRenderer&#39;; import BaseRenderer, { BaseRendererTester } from &#39;../../renderer/BaseRenderer&#39;; import { vanillaCells, vanillaRenderers, vanillaStyles, JsonFormsStyleContext, } from "@jsonforms/vanilla-renderers"; import { useTranslation } from "react-i18next"; import formSchema from "./form-schema.json"; import formUischema from "./form-ui-schema.json"; import liststyle from "../../../style/design-system-form.json"; import &#39;../style/global.css&#39;; import &#39;../style/S-ECSCM.css&#39;; import "tabulator-tables/dist/css/tabulator.min.css"; import { ReactTabulator, ReactTabulatorOptions } from &#39;react-tabulator&#39;; import { useUnifiedForm } from &#39;../../../yupCommon/useUnifiedForm&#39;; import { useYupI18n } from &#39;../../../yupCommon/useYupI18n&#39;; import { createValidationSchema } from &#39;./validationSchemas&#39;; import initdata from &#39;./table-data.json&#39;; const tableData = initdata["table"]; const styleContextValue = { styles: [...vanillaStyles, ...liststyle] }; import { rankWith, scopeEndsWith, and, or, schemaTypeIs } from &#39;@jsonforms/core&#39;; import useProtectedNavigate from "../../../services/useProtectedNavigate"; import * as Yup from "yup"; import $ from &#39;jquery&#39;; import { useHttpClient } from &#39;../../httpClient&#39;; import { useUserData } from &#39;../../../UserContext&#39;; const sampleData = { "number": "111", "parts": "222", "partsid": "", "products": "", "productsid": "", "shop": "", "shopid": "", "status-category": "", "survey-category": ["test1", "test2"], "request-category": "", "request-dept": "", "request-person": "", "requestdate_min": "", "requestdate_max": "", "expected_response_min": "", "expected_response_max": "", "response_date_min": "", "response_date_max": "" }; const SECSCMTEST = () => { const { t: translation, i18n: i18nInstance } = useTranslation(); const locale = i18nInstance.language; const protectedNavigate = useProtectedNavigate(); const [statusSelected, setStatusSelected] = useState(false); const tableRef = React.useRef<{table?: Tabulator;}>(null); const [tableData, setTableData] = useState([]); const [totalRecords, setTotalRecords] = useState(0); const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(0); // 使用多语言 Yup 配置 const { createLabeledSchema, currentLang } = useYupI18n(); // 创建多语言验证 schema const validationSchema = useMemo(() => { const baseSchema = createValidationSchema(currentLang); return createLabeledSchema(baseSchema); }, [createLabeledSchema, currentLang]); // 使用改进后的统一表单管理(现在支持输入法兼容和多语言) const { formData, validationErrors, isValid, isSubmitting, updateFormData, updateField, registerField, getFieldValue, getFieldError, resetForm, submitForm } = useUnifiedForm({ schema: validationSchema, initialData: sampleData, debounceMs: 500, // 设置防抖延迟为500ms onSubmit: (data) => { console.log("表单提交数据:", data); alert("表单校验通过,数据提交成功!"); } }); // 添加画面变更时触发的方法,将错误消息放到 validation input-description 中 const updateValidationMessages = useCallback(() => { const validationElements = document.getElementsByClassName(&#39;validation&#39;); Array.from(validationElements).forEach(element => { element.innerHTML = &#39;&#39;; }); Object.entries(validationErrors).forEach(([field, error]) => { // 修正:使用正确的模板字符串语法和原生 DOM API const controlDiv = document.querySelector(`div[id*="${field}"]`); if (controlDiv) { // 在控制容器中查找验证消息容器 const validationDiv = controlDiv.querySelector(&#39;.validation&#39;); if (validationDiv) { // 更新错误消息内容和样式 validationDiv.textContent = error || &#39;&#39;; const htmlElement = validationDiv as HTMLElement; if (error) { htmlElement.style.color = &#39;#ff4444&#39;; htmlElement.style.fontSize = &#39;12px&#39;; htmlElement.style.marginTop = &#39;4px&#39;; htmlElement.style.fontWeight = &#39;400&#39;; htmlElement.style.display = &#39;block&#39;; } else { htmlElement.style.color = &#39;&#39;; htmlElement.style.fontSize = &#39;&#39;; htmlElement.style.marginTop = &#39;&#39;; htmlElement.style.fontWeight = &#39;&#39;; htmlElement.style.display = &#39;none&#39;; } } } }); }, [getFieldError]); const httpClient = useHttpClient(); const getTableData = (page) => { var obj: any = {}; const numbers = $("select[id^=&#39;#/properties/number&#39;]"); if(numbers.length != 0){ obj[&#39;number&#39;] = $("select[id^=&#39;#/properties/number&#39;]")[0].value; }else{ obj[&#39;number&#39;] = null; } obj[&#39;page&#39;] = page; obj[&#39;size&#39;] = 10; httpClient.post(&#39;/SECSCMTEST/getTableData&#39;, obj) .then(response => { console.log(&#39;success:&#39;, response.data); setTableData(response.data.table || []); setTotalRecords(response.data.total || 0); // 保存总记录数 setCurrentPage(page); // 在获取数据后更新最大页数 if (tableRef.current) { const maxPage = Math.ceil((response.data.total || 0) / 10); try { // 尝试不同的方法设置最大页数 if (tableRef.current.setMaxPage) { tableRef.current.setMaxPage(maxPage); } else if (tableRef.current.modules && tableRef.current.modules.page) { tableRef.current.modules.page.setMaxPage(maxPage); } console.log(&#39;设置最大页数成功:&#39;, maxPage); } catch (error) { console.error(&#39;设置最大页数失败:&#39;, error); } } }) .catch(error => { console.error(&#39;Save failed:&#39;, error); }); }; const { userData } = useUserData(); useEffect(() => { if(userData && userData.role){ getTableData(1); } }, []); // 监听 validationErrors 变化,自动更新错误消息显示 useEffect(() => { // 使用 setTimeout 确保 DOM 已经渲染完成 const timer = setTimeout(() => { updateValidationMessages(); }, 100); return () => clearTimeout(timer); }, [validationErrors, updateValidationMessages]); useEffect(() => { if (tableRef.current && tableRef.current.table) { const tabulator = tableRef.current.table; setTimeout(() => { try { tabulator.setColumns(statusSelected ? Columns1 : Columns2); } catch (error) { console.error("Failed to refresh table:", error); } }, 100); } }, [statusSelected]); const cellClickFunc = (_e: any, cell: any) => { const _rowdata = cell.getRow().getData(); const _investigation_no = _rowdata.investigation_no; const _investigation_status = _rowdata.investigation_status; const _representative_supplier_name = _rowdata.representative_supplier_name; if (_investigation_no && _investigation_status && _representative_supplier_name) { protectedNavigate(`/SECSCM005?no=${_investigation_no}&status=${_investigation_status}&date=${_representative_supplier_name}`) } else { console.error("Row data is missing required fields for navigation:", _rowdata); } } const baseColumnConfig = { headerHozAlign: &#39;center&#39; as const, hozAlign: &#39;left&#39; as const, vertAlign: &#39;center&#39; as const, cellClick: (_e: any, cell: any) => { cellClickFunc(_e, cell) } }; const Columns1 = [ { title: &#39;ID&#39;, formatter: "rownum", hozAlign: "center" as const, headerHozAlign: "center" as const, width: 40, headerSort: false }, { title: "", formatter: "rowSelection", titleFormatter: "rowSelection", hozAlign: "center" as const, headerHozAlign: "center" as const, headerSort: false, width: 40 }, { ...baseColumnConfig, title: &#39;調査依頼ID&#39;, field: &#39;investigation_no&#39;}, { ...baseColumnConfig, title: &#39;調査対象&#39;, field: &#39;representative_part_name&#39;}, { ...baseColumnConfig, title: &#39;依頼区分&#39;, field: &#39;representative_part_id&#39;}, { ...baseColumnConfig, title: &#39;依頼部門&#39;, field: &#39;purchased_item_name&#39;}, { ...baseColumnConfig, title: &#39;回答希望日&#39;, field: &#39;representative_supplier_name&#39;}, { title: "个人信息", headerHozAlign: &#39;center&#39; as const, columns: [ { ...baseColumnConfig, title: &#39;最短回答予定日&#39;, field: &#39;representative_supplier_id&#39;}, { ...baseColumnConfig, title: &#39;最長回答予定日&#39;, field: &#39;investigation_status&#39;}, ] }, { ...baseColumnConfig, title: &#39;依頼担当者&#39;, field: &#39;purchased_item_id&#39;}, ]; const Columns2 = [ { title: "", formatter: "rowSelection", titleFormatter: "rowSelection", hozAlign: "center" as const, headerHozAlign: "center" as const, headerSort: false, width: 40 }, { ...baseColumnConfig, title: &#39;調査依頼ID&#39;, field: &#39;investigation_no&#39;}, { ...baseColumnConfig, title: &#39;調査対象&#39;, field: &#39;representative_part_name&#39;}, { ...baseColumnConfig, title: &#39;依頼区分&#39;, field: &#39;representative_part_id&#39;}, { ...baseColumnConfig, title: &#39;依頼部門&#39;, field: &#39;purchased_item_name&#39;}, { ...baseColumnConfig, title: &#39;回答希望日&#39;, field: &#39;representative_supplier_name&#39;}, { ...baseColumnConfig, title: &#39;最短回答予定日&#39;, field: &#39;representative_supplier_id&#39;}, { ...baseColumnConfig, title: &#39;最長回答予定日&#39;, field: &#39;investigation_status&#39;}, { ...baseColumnConfig, title: &#39;依頼担当者&#39;, field: &#39;purchased_item_id&#39;}, ]; const handleFormChange = useCallback((data: any) => { updateFormData(data); setStatusSelected(data["status-category"] && data["status-category"] !== ""); // 表单数据变化时也更新验证消息 setTimeout(() => { updateValidationMessages(); }, 100); }, [updateFormData, updateValidationMessages]); const handleClearForm = () => { resetForm(); }; const ErrorMessage = ({ fieldName }: { fieldName: keyof typeof sampleData }) => { const error = getFieldError(fieldName); return error ? <div style={{ color: "red", fontSize: "12px", marginTop: "2px" }}>{error}</div> : null; }; // 远程数据加载函数 const fetchRemoteData = (url, config, params) => { return new Promise((resolve, reject) => { // 模拟 API 参数(实际项目替换为真实 API) const queryParams = new URLSearchParams({ page: params.page, size: params.size, sort: params.sorters.map(s => `${s.field}:${s.dir}`).join(&#39;,&#39;) }); // 实际项目使用 fetch/axios 替换此部分 setTimeout(() => { const mockData = { last_page: 5, data: Array.from({ length: params.size }, (_, i) => ({ representative_part_id: i + (params.page - 1) * params.size, investigation_no: `用户 ${i + 1}`, representative_part_name: `user${i + 1}@example.com`, representative_supplier_name: `职位 ${Math.floor(Math.random() * 10)}` })) }; resolve(mockData); }, 500); }); }; const options: ReactTabulatorOptions = { renderHorizontal: "virtual", layout: "fitDataTable", selectable: true, pagination: "remote", paginationSize: 10, // 远程分页控制属性 page: 1, // 当前页码 paginationSizeSelector: [10, 25, 50, 100], // 可选的每页条数 // 分页回调函数 //pageLoaded: (pageno: number) => { // if (pageno !== currentPage) { // getTableData(pageno); // } //}, ajaxRequestFunc: fetchRemoteData, ajaxResponse: function(url, params, response) { return { data: response.data, last_page: response.last_page }; } }; const renderers = [ ...vanillaRenderers, { tester: BaseRendererTester, renderer: BaseRenderer } //{ tester: EnumSelectRendererTester, renderer: EnumSelectRenderer } ]; // 修改测试函数,尝试多种方法 const checkTableRef = () => { console.log(&#39;手动检查 tableRef:&#39;); console.log(&#39;tableRef.current:&#39;, tableRef.current); if (tableRef.current) { console.log(&#39;找到 Tabulator 实例&#39;); console.log(&#39;可用方法:&#39;, Object.getOwnPropertyNames(tableRef.current.current)); console.log(&#39;modules:&#39;, tableRef.current.modules); const maxPage = Math.ceil(totalRecords / 10); console.log(&#39;计算的最大页数:&#39;, maxPage); // 尝试多种设置方法 try { if (tableRef.current.current.setMaxPage) { tableRef.current.current.setMaxPage(maxPage); console.log(&#39;方法1成功: setMaxPage&#39;); } else if (tableRef.current.modules && tableRef.current.modules.page) { if (tableRef.current.modules.page.setMaxPage) { tableRef.current.modules.page.setMaxPage(maxPage); console.log(&#39;方法2成功: modules.page.setMaxPage&#39;); } } else { // 尝试重新设置选项 const newOptions = { ...options, maxPage }; console.log(&#39;尝试重新设置选项:&#39;, newOptions); } } catch (error) { console.error(&#39;所有方法都失败:&#39;, error); } } }; return ( <div id="content"> <br /> <details className="details"> <summary className="details-summary">{translation(&#39;common.button.show-select-menu.label&#39;,&#39;no label&#39;)}</summary> <form onSubmit={submitForm}> {/* JsonForms 部分 */} <div style={{ marginBottom: "20px" }}> <JsonFormsStyleContext.Provider value={styleContextValue}> <JsonForms i18n={{locale: locale, translate: (key: string, defaultMessage?: string) => translation(key, defaultMessage || &#39;&#39;)}} schema={formSchema} uischema={formUischema} data={formData} renderers={renderers} cells={vanillaCells} onChange={({ data }) => handleFormChange(data)} validationMode="NoValidation" /> </JsonFormsStyleContext.Provider> </div> {/* 原生HTML表单部分 - 现在支持输入法兼容 */} <div style={{ border: "1px solid #fff"}}> <div className="control" id="#/properties/tel"> <label htmlFor="tel-input" className="label">电话:</label> <input className="validate valid input text-field" id="tel-input" name="tel" type="text" ref={(ref) => registerField(&#39;tel&#39;, ref)} defaultValue={getFieldValue(&#39;tel&#39;)} /> <ErrorMessage fieldName="tel" /> </div> </div> <div id="button-right"> <input type="button" className="button" style={{ marginRight: "20px" }} value={translation(&#39;common.button.clear.label&#39;,&#39;no label&#39;)} onClick={handleClearForm} /> <input type="submit" className="button" value={translation(&#39;common.button.select.label&#39;,&#39;no label&#39;)} disabled={!isValid || isSubmitting} style={{ opacity: (isValid && !isSubmitting) ? 1 : 0.5 }} /> {/* 添加测试按钮 */} <input type="button" className="button" style={{ marginLeft: "20px", backgroundColor: "#ff6600" }} value="测试tableRef" onClick={checkTableRef} /> </div> </form> </details> <br /> <div> <ReactTabulator onRef={(instance) => { tableRef.current = instance; }} columns={Columns2 as any} data={[]} options={options} /> </div> <div style={{ marginTop: "10px" }}> <input className="button" type="button" style={{ marginRight: "30px" }} value={translation(&#39;common.button.select-all.label&#39;,&#39;no label&#39;)} /> <input type="button" className="button" value={translation(&#39;common.button.CSV-download.label&#39;,&#39;no label&#39;)} /> </div> </div> ); }; export default SECSCMTEST; 找出我这个文件的错误
最新发布
07-10
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值