关于如何在html属性中编写 async/await的问题?

淋着
  • 272
前后端不分离项目
以前的写法 cstbtn是后端的一个控件,同时兼顾vue写法
<div id="app">
    <cstbtn data-ajax="true" 
        data-ajax-begin="return confirm('确认删除?')"
        data-ajax-method="POST" 
        data-ajax-loading="#div_loading"
        data-ajax-success="viewHelper.onDataDelete">
  </cstbtn>
</div>
<script>
    var vm = new Vue({
        el: '#app'
    })
</script>

我想把原生的confirm改成elementui的confirm

var viewHelper = {
     confirm: async function (msg) {
        let response = await rootApp.$confirm(msg, '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        }).catch(() => {});
        return response == 'confirm'
    },
}

我这样写就是一个promise,并不是true或者false

<cstbtn ...
    data-ajax-begin="return viewHelper.confirm('确认删除?')"
    ...>
</cstbtn>

我改成return await viewHelper.confirm('确认删除?')就报错,必须async函数才行,
然后我就不知道怎么改了
image.png

哪位大佬知道怎么改啊?
cstbtn这个后端控件还是保留,不能修改

找到解决方案了,这是jquery.unobtrusive-ajax.js这个插件导致的,直接改源码就行了,让他识别promise就行了

回复
阅读 641
2 个回答

像你这样写应该是不行,毕竟 async/await函数也只是 Promise 的语法糖,尽我所知内联代码是不支持全局 await 的。
我有一种思路,不知道可行与否:

  1. 第一次调用 confirm 的时候返回 false,并弹窗询问;
  2. 获得询问结果后,存储此结果,然后触发 <cstbtn> 重渲染,以触发第二次调用;
  3. 第二次读取的时候,就能拿到存储的询问结果了。
{
    data: {
        rerenderKey: 0,
        confirmResult: false,
        confirmState: 0
    },
    methods: {
        confirm(msg){
            const {confirmResult, confirmState} = this;
            if(confirmState === 0){
                // 第一次调用,弹窗询问
                this.confirmState = 1;
                rootApp.$confirm(msg, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then((result) => {
                    // 拿到询问结果,记录此结果
                    this.confirmResult = result;
                    if(result){
                        // 触发渲染,这样就会触发第二次调用 confirm
                        this.rerenderKey ++;
                    } else {
                        // 重置询问状态,不用再触发一次渲染
                        this.confirmState = 0;
                    }
                }).catch(() => {
                });
            } else {
                this.confirmState = 0; // 重置询问状态
                this.confirmResult = false; // 重置询问结果
                return confirmResult
            }
        }
    }
}
<cstbtn
      :key="rerenderKey"
      data-ajax="true" 
      data-ajax-begin="return viewHelper.confirm('确认删除?')"
      data-ajax-method="POST" 
      data-ajax-loading="#div_loading"
      data-ajax-success="viewHelper.onDataDelete"
/>
这里我用了 :key="rerenderKey" 这个 Vue 模板语法,不过仔细看了题主的代码,才发现 <cstbtn> 不在 Vue 应用中,不知道实际应当作何处理,但是大致意思题主应该明白:拿到询问结果为True之后,想方设法让 <cstbtn> 立即再调用一遍 viewHelper.confirm,这样就能走完删除的流程了
按照这个思路,代码可以精简不少。

这么写呢?

data-ajax-begin="viewHelper.confirm('确认删除?')"
宣传栏