以文本方式查看主题

-  Foxtable(狐表)  (http://foxtable.net/bbs/index.asp)
--  专家坐堂  (http://foxtable.net/bbs/list.asp?boardid=2)
----  loadchildren的问题反馈  (http://foxtable.net/bbs/dispbbs.asp?boardid=2&id=177482)

--  作者:reachtone
--  发布时间:2022/5/24 11:50:00
--  loadchildren的问题反馈
表A是父表,表B是子表。
在表A的afterload事件中使用了loadchildren,也就是在表A重载数据时,会自动重载子表数据。
问题是,在表A重载后,想同时移除表B中的记录,却无效!(参考例子中的第1个按钮代码)

 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:管理项目2.table



--  作者:有点蓝
--  发布时间:2022/5/24 11:55:00
--  
Foxtable是事件驱动的,按钮2的执行会比子表的加载早。延迟一下再调用按钮2

这个逻辑是不合理的,既然想移除子表的数据,又何必做父子表的同步加载!

--  作者:reachtone
--  发布时间:2022/5/24 11:58:00
--  
特殊情况下用到的,只是为了说明问题,简化的代码。
--  作者:reachtone
--  发布时间:2022/5/24 12:15:00
--  
试了,加了5秒延迟,仍然无效:
With DataTables("表A")
    .LoadFilter = "id=3"
    .Load
End With
sleep(5000)
e.Form.Controls("Button2").performClick

--  作者:有点蓝
--  发布时间:2022/5/24 13:35:00
--  
那就是事件触发顺序的问题了。这种情况无解。

用全局变量控制一下,表A的afterload事件加个判断,子表是否需要加载

--  作者:reachtone
--  发布时间:2022/5/31 11:57:00
--  
继续反映loadchildren的问题,总觉得这个loadchildren不太合理。如下例,这里新增加一个按钮,用于弹出子表的loadfilter加载条件。
通过以下两种方式操作就能看出问题所在:
1、先点击“重载子表”再点击“子表加载条件”。
2、先点击“重载子表”、再点击“重载id为2的子表”最后再点击“子表加载条件”。
说白了,问题的根源就在于,在父表的afterload事件中执行了loadchildern之后,接着给子表再设置重载条件就无效了。很显然,这并不合理,因为在子表数据重载完成之后,对其再做过滤,是很常见的事。
 下载信息  [文件大小:   下载次数: ]
图片点击可在新窗口打开查看点击浏览该文件:管理项目2.table



--  作者:有点蓝
--  发布时间:2022/5/31 14:25:00
--  
先来捋一捋

1、先点击“重载子表”,触发“重载子表”的click事件
2、“重载子表”的click事件加载表A,表A加载后会触发表格的afterload事件,很明显,afterload事件必须等待表格加载完毕才能触发,所以并不是马上触发的,我估计是使用回调机制触发(类似weui里ajax函数submitAjaxForm的回调参数用法),而按照.net的机制,事件不是异步的,新的事件必须等待之前的事件执行完毕,也就是afterload事件必须等待“重载子表”的click事件执行完毕。
3、“重载子表”的click事件加载表A后紧接着就执行按钮“重载id为2的子表”的代码,注意performClick会马上执行按钮2的代码,而不是等待“重载子表”的click事件执行完毕才会执行,也就是这时“重载子表”的click事件的代码还不算执行完毕,同时表格的afterload事件也还在等待执行中。等“重载子表”的所有代码执行完毕后,“重载子表”的click事件才算执行完毕,才会执行表格的afterload事件

如果要达到效果,需要延迟执行按钮2的代码,利用计时器事件,下面用法计时器事件触发会在表格afterload之后
窗口timetick事件
e.Form.TimerEnabled = False
e.Form.Controls("Button2").performClick

“重载子表”的click事件
With DataTables("表A")
    .LoadFilter = ""
    .Load
End With
e.Form.TimerInterval = 100
e.Form.TimerEnabled = True
--  作者:狐狸爸爸
--  发布时间:2022/5/31 14:32:00
--  
你把第二个按钮的代码改为:

DataTables("表B").LoadFilter = "pid=2"
DataTables("表B").Load
MessageBox.Show(DataTables("表B").LoadFilter)

可以看到你设置的条件确实生效了,而且确实只加载了pid为2行,只是单击对话框的确定按钮之后,才开始执行LoadChidren,所以看起来子表条件没有生效。

所以这个不是Loadchildren问题,是代码代码执行顺序的问题:

AfterLoad事件并不会在Load执行完毕之后马上触发,而是等所有代码执行完毕,系统空闲后才触发

这个执行顺序目前时不能调整的,首先当时这么设计肯定有原因,其次调整了可能会衍生出其他问题。

所以特殊情况,就不要在AfterLoad事件执行LoadChidren了,父表的load和loadchildren都放在同一个按钮吧,确保会按预期的顺序执行。
[此贴子已经被作者于2022/5/31 15:00:00编辑过]

--  作者:reachtone
--  发布时间:2022/5/31 14:58:00
--  
谢谢楼上两位的回复,看来还是要继续变通处理一下