找回密码
 立即注册

QQ登录

只需一步,快速开始

IT-Weaver

初级会员

20

主题

76

帖子

238

积分

初级会员

积分
238
IT-Weaver
初级会员   /  发表于:2022-1-12 08:54  /   查看:1603  /  回复:6
1金币
本帖最后由 IT-Weaver 于 2022-1-12 09:30 编辑

之前在论坛下载的demo中,一般都是以顺序形式写的代码,如:
  1. var asyncSum = function () {
  2.     };
  3.     asyncSum.prototype = new GC.Spread.CalcEngine.Functions.AsyncFunction("ASUM", 1, 255);
  4.     asyncSum.prototype.defaultValue = function () {
  5.         return "Loading...";
  6.     };
  7.     asyncSum.prototype.evaluateAsync = function (context) {
  8.         // use setTimeout to simulate server side evaluation
  9.         // in read world it maybe an ajax post to server for evaluation
  10.         var args = arguments;
  11.         setTimeout(function () {
  12.             var result = 0;
  13.             for (var i = 1; i < args.length; i++) {
  14.                 result += args[i];
  15.             }
  16.             result *= 2;
  17.             context.setAsyncResult(result);
  18.         }, 2000);
  19.     };

  20.     var GetNumberFromServer = function () {
  21.     };
  22.     GetNumberFromServer.prototype = new GC.Spread.CalcEngine.Functions.AsyncFunction("GETNUMBERFROMSERVER", 1, 2);
  23.     GetNumberFromServer.prototype.evaluate = function (context, arg1, arg2) {
  24.         setTimeout(function () {
  25.             var value = Math.random() + 1;
  26.             context.setAsyncResult(value);
  27.         }, 500);
  28.     };
  29.     GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("GETNUMBERFROMSERVER", new GetNumberFromServer());

  30.     var GetTimeFromServer = function () {
  31.     };
  32.     GetTimeFromServer.prototype = new GC.Spread.CalcEngine.Functions.AsyncFunction("GETTIMEFROMSERVER");
  33.     GetTimeFromServer.prototype.evaluate = function (context) {
  34.         setTimeout(function () {
  35.             var date = new Date();
  36.             context.setAsyncResult(date);
  37.         }, 500);
  38.     };
  39.     GetTimeFromServer.prototype.evaluateMode = function () {
  40.         return 2;
  41.     };
  42.     GetTimeFromServer.prototype.interval = function () {
  43.         return 1000;
  44.     };
  45.     GC.Spread.CalcEngine.Functions.defineGlobalCustomFunction("GETTIMEFROMSERVER", new GetTimeFromServer());

  46.     var sheet = spread.sheets[0];
  47.     sheet.suspendPaint();
  48.     sheet.options.allowCellOverflow = true;

  49.     sheet.setArray(0, 0, [[5, 15]]);
  50.     sheet.addCustomFunction(new asyncSum());

  51.     sheet.setText(1, 1, 'ASUM(A1,B1)');
  52.         for(i=0;i<3001;i++){
  53.                 sheet.setFormula(i, 7, "ASUM(A1,B1)");
  54.         }
  55.     sheet.setText(2, 1, 'SUM(A1,B1)');
  56.     sheet.setFormula(1, 2, "ASUM(A1,B1)");
  57.     sheet.getCell(1, 2).foreColor("green");
  58.     sheet.setFormula(2, 2, "SUM(A1,B1)");
复制代码

但是在我们实际需求中,一般这些动态类会以引用形式进行编写,如:
  1. import { asyncCustomFormulaV12 } from '../js/report/customFormula.js'

  2. let customFunction = new asyncCustomFormulaV12(customFormula.fName);
  3.             activeSheet.addCustomFunction(customFunction);
复制代码
那么现在有这样一个问题,当我引用时,我就无法在
  1. asyncCustomFormulaV12.prototype = new GC.Spread.CalcEngine.Functions.AsyncFunction();
复制代码
继承原型链时,动态传递name,minArgs,maxArgs等参数,请问这些情景下,应该如何操作,才可以让动态公式生效,在网上搜了好多相关原型链继承的方式,都尝试,依然在引用时报“无效的自定义函数”,但是如官方demo写在页面里,就可以绑定。

最佳答案

查看完整内容

可以参考附件的方式引用自定义公式

6 个回复

倒序浏览
最佳答案
最佳答案
Derrick.Jiao讲师达人认证 悬赏达人认证 SpreadJS 开发认证
论坛元老   /  发表于:2022-1-12 08:54:14
来自 5#
可以参考附件的方式引用自定义公式
image.png607299193.png

init_excel 2.zip

180.24 KB, 下载次数: 39

回复 使用道具 举报
IT-Weaver
初级会员   /  发表于:2022-1-12 08:56:21
2#
本帖最后由 IT-Weaver 于 2022-1-12 09:26 编辑

我们动态自定义函数现在是这么定义的
  1. export const asyncCustomFormulaV12 = function (fName) {
  2.   GC.Spread.CalcEngine.Functions.AsyncFunction.call(this,fName,1,255);
  3.   this.typeName = fName;
  4.   this.name = fName;
  5.   this.maxArgs = 255;
  6.   this.minArgs = 1;
  7.   // GC.Spread.CalcEngine.Functions.AsyncFunction.call(customFormula.fName,1,255,"");
  8. };
  9. asyncCustomFormulaV12.prototype = new GC.Spread.CalcEngine.Functions.AsyncFunction();
  10. asyncCustomFormulaV12.prototype.defaultValue = function () {
  11.     return "Loading...";
  12. };
  13. asyncCustomFormulaV12.flag = false
  14. asyncCustomFormulaV12.prototype.loadValue = false
  15. asyncCustomFormulaV12.randomNum = 0
  16. asyncCustomFormulaV12.prototype.AsyncFunctions = {}
  17. asyncCustomFormulaV12.prototype.evaluateAsync = function (context,args) {
  18.     if (asyncCustomFormulaV12.flag) {
  19.       if (this.name) {
  20.         const p = toJsonPase([args]);
  21.         if (p === null) {
  22.           context.setAsyncResult('');
  23.           return;
  24.         }
  25.         context.randomNum = asyncCustomFormulaV12.randomNum;
  26.         asyncCustomFormulaV12.prototype.AsyncFunctions[this.name].doCalculate(context, p)
  27.         // var text = context.ctx.source._sheet.getValue(context.ctx.row, context.ctx.column);
  28.         var text = context.ctx.source.getValue(context.ctx.row,context.ctx.column);
  29.         if (text === '#NAME?' || text === '#VALUE!' || text === 'Loading...' || text === null || typeof text === 'object') {
  30.           context.setAsyncResult('');
  31.         }
  32.       }
  33.     }else{
  34.       if (asyncCustomFormulaV12.prototype.loadValue) {
  35.         // eslint-disable-next-line no-redeclare
  36.         // var text = context.ctx.source._sheet.getValue(context.ctx.row, context.ctx.column)
  37.         var text = context.ctx.source.getValue(context.ctx.row,context.ctx.column);
  38.         if (text === '#NAME?' || text === '#VALUE!' || text === 'Loading...' || text === null || typeof text === 'object') {
  39.           context.setAsyncResult('');
  40.         } else {
  41.           // context.setAsyncResult(context.ctx.source._sheet.getValue(context.ctx.row, context.ctx.column))
  42.           context.setAsyncResult(context.ctx.source.getValue(context.ctx.row,context.ctx.column));
  43.         }
  44.       } else {
  45.         // console.log(context.ctx.source.getValue(context.ctx.row,context.ctx.column));
  46.         context.setAsyncResult('');
  47.       }
  48.     }
  49. };
复制代码
  1. function toJsonPase (params) {
  2.   let res={};
  3.   if(!isNull(params[0])){
  4.     var filedArray=params[0].toString().split(';');
  5.     filedArray.forEach(one=>{
  6.       var itemArray=one.split("=");
  7.       res[itemArray[0]]=itemArray[1].split(',');
  8.     })
  9.   }
  10.   return res;
  11. }
复制代码

引用后,new出来之后会报“无效的自定义函数”。

回复 使用道具 举报
IT-Weaver
初级会员   /  发表于:2022-1-12 09:29:22
3#
这段代码写在业务页面,放到我得动态公式绑定的循环里,直接在 asyncCustomFormulaV12.prototype = new GC.Spread.CalcEngine.Functions.AsyncFunction(); 时,传递动态公式名字,是可以生效的,但是现在因为要规范项目代码引出来了就不知道该怎么写了。试了网上很多种原型链继承方法,都不生效。
回复 使用道具 举报
IT-Weaver
初级会员   /  发表于:2022-1-12 10:28:28
4#
image.png362760009.png

这是调用结果。
回复 使用道具 举报
IT-Weaver
初级会员   /  发表于:2022-1-13 15:12:06
6#
Derrick.Jiao 发表于 2022-1-12 12:01
可以参考附件的方式引用自定义公式

解决了,你的方法是可用的,结贴吧。
回复 使用道具 举报
Derrick.Jiao讲师达人认证 悬赏达人认证 SpreadJS 开发认证
论坛元老   /  发表于:2022-1-13 16:58:33
7#
IT-Weaver 发表于 2022-1-13 15:12
解决了,你的方法是可用的,结贴吧。

好的,有新问题请开新帖交流~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部