FineUICore-F.doPostBack的Promise改造

688 阅读2分钟

1. 需求

环境:FineUICore 本人JS比后台代码多

实际开发中有一个页面是一个父页面套两个iframe子页面,通过js进行交互;

结构图1:

其中有一个方法,由子页面发起,由父页面提交到后台处理(因为参数来自于不同页面),再返回结果由父页面和子页面分别处理;

交互图2:

交互图3:

其中的一些关键方法如下:

关键方法图4:

关键方法图5:

2. 引出问题

这里,父子页面的Save和SaveDone都是非线性的,断开的,如果 有一部分参数想传到SaveDone中还得靠后台中转或存到其他缓存中,而且这样写不方便阅读。

问题图6:

3. 理想策略

这里就要引出js的await方法,处理异步为同步,可以解决上面的问题,让写起来更符合阅读逻辑;

理想写法图7:

4. 改造

如果想要写成await写法,核心F.doPostBack就要返回Promise对象;

js中新建一个方法F.doPostBackP,后台将通过guid找到前台的Promise;

    /**
	 * 2021年12月7日 更新了一下下
     * 返回Promise使前台可以同步
     * @param {Object} opts 只接收Obj数据
     */
    F.doPostBackP = (opts) => {
        const _complete = opts.complete;
        const autoLoading = opts.autoLoading;
        const guid = GetGuid();
        opts.complete = (...coms) => {
            if (autoLoading) {
                autoLoading.split(",").forEach(id => {
                    if (F.ui[id] && F.ui[id].hideLoading) {
                        F.ui[id].hideLoading();//showLoading
                    }
                });
            }
            _complete && _complete.apply(this, [...coms, guid]);
        };
        return new Promise(r => {
            //将r放到指定id中 参数args由后台赋值
            F.doPostBack[guid] = r;
            if (!opts.params) {
                opts.params = {}
            }
            //后台body中接收postGUID 参照UIdoPostBack
            opts.params.postGUID = guid;
            if (autoLoading) {
                autoLoading.split(",").forEach(id => {
                    if (F.ui[id] && F.ui[id].showLoading) {
                        F.ui[id].showLoading();//hideLoading
                    }
                });

                opts.enableAjaxLoading = false;
            }
            //执行原始回发
            F.doPostBack(opts);
        });
    }

在后台的BaseController中 , 增加执行方法,执行结果

    /// <summary>
    /// 返回参数 注意接收json格式,不支持字符串 配合 doPostBackP
    /// </summary>
    /// <param name="json"></param>
    public void UIdoPostBack(string json)
    {
      string postGUID = string.Empty;
      var Form = FineUICore.PageContext.Current.Request.Form;
      if (Form.ContainsKey("postGUID"))
      {
        postGUID = Form["postGUID"];
      }
      var Script = $"F.doPostBack['{postGUID}']({json});";
      FineUICore.PageContext.RegisterStartupScript(Script);
    }
  • 这里后台直接输出'""'格式会报错,所以当前只写了输出对象;

最后将理想写法中F.doPostBack改为F.doPostBackP,后台直接调用UIdoPostBack("{msg:'保存成功'}");即可;