Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript jQuery、Dialog、Tabs和DataTables:如何在继续之前等待一个完成?_Javascript_Jquery_Jquery Ui_Datatables_Jquery Datatables - Fatal编程技术网

Javascript jQuery、Dialog、Tabs和DataTables:如何在继续之前等待一个完成?

Javascript jQuery、Dialog、Tabs和DataTables:如何在继续之前等待一个完成?,javascript,jquery,jquery-ui,datatables,jquery-datatables,Javascript,Jquery,Jquery Ui,Datatables,Jquery Datatables,我有一个棘手的问题,可以用链式回调来解决,但这会导致相当复杂的代码 我有一些嵌套组件:一个jQueryUI对话框。里面有jQueryUI标签。在每个选项卡中,我都有一个DataTables组件,称为AJAX数据 我的问题是,当我加载对话框中的所有HTML时,所有内容都并行启动:选项卡试图创建自己,而每个DataTable同时收集数据 结果是一团乱麻:选项卡没有包含正确的元素,因为每个DataTable在选项卡初始化后都会在DOM上创建新节点。该对话框采用了错误的维度,因为DOM在初始化时很小,但

我有一个棘手的问题,可以用链式回调来解决,但这会导致相当复杂的代码

我有一些嵌套组件:一个jQueryUI对话框。里面有jQueryUI标签。在每个选项卡中,我都有一个DataTables组件,称为AJAX数据

我的问题是,当我加载对话框中的所有HTML时,所有内容都并行启动:选项卡试图创建自己,而每个DataTable同时收集数据

结果是一团乱麻:选项卡没有包含正确的元素,因为每个DataTable在选项卡初始化后都会在DOM上创建新节点。该对话框采用了错误的维度,因为DOM在初始化时很小,但在每个DataTable显示数据时会长大

为了让事情顺利进行,我需要:

1) Wait for each DataTable to initialize.
2) When they're all done, initialize the Tabs.
3) When Tabs are ready, finally open the Dialog.
有没有一个简单的方法可以做到这一点??我目前正在使用大量回调,所有内容都是动态的,由数据库驱动的,因此我必须进行大量的泛化,几乎没有任何内容可以硬编码。这东西已经能用了,但它很难看

在这种情况下,如果可以的话,我会关闭JavaScript异步行为,并将其全部同步并按顺序进行


也许jqueryqueue、promise或类似的东西可以帮助我?任何帮助都将不胜感激

我已经找到了一个合适的解决方案,所以我将在这里发布它,以帮助其他面临类似问题的人

首先,我发现DataTables在创建时触发了一个事件。这是“初始化”事件:

其次,我的另一个问题是,在初始化选项卡之前,我必须等待的数据表数量不确定。因此,我创建了一个名为RenderManager的小函数来跟踪我的所有数据表。当最后一个完成时,将调用回调。我将此函数设置为非常通用的函数,因此它可以用于在继续之前必须等待多个并行处理完成的任何情况:

function RenderManager(action, id, callback) 
{
  if(typeof RenderManager.groups == 'undefined' ) RenderManager.groups = {};

  switch(action)
  {
    case "init":
      RenderManager.groups[id] = { _callback:callback, _counter:0 };
    break;
    case "add":
      if(typeof RenderManager.groups[id] == 'undefined' ) 
        console.log('Group "'+id+'" referenced before init.');
      else 
        RenderManager.groups[id]._counter++;
    break;
    case "remove":
      if(typeof RenderManager.groups[id] == 'undefined' ) 
        console.log('Group "'+id+'" referenced before init.');
      else
      {
        RenderManager.groups[id]._counter--;
        if(RenderManager.groups[id]._counter == 0) 
          RenderManager.groups[id]._callback();
      }
    break;
  }
}
用法很简单:首先,使用init调用它,以通知组名和所需的回调:

RenderManager('init', 'MyGroup', function() { CreateTabs(); });
对于创建的每个数据表(或启动的并行进程),将其添加到组中:

RenderManager('add', 'MyGroup');
然后使用以下命令将
remove
绑定到每个数据表的
init
事件(或任何并行过程的完成):

就这样!当最后一个数据表完成它的作业时,
CreateTabs()


如您所见,此函数只是一个计数器:当“堆栈”返回到零时,将触发回调。它可以通过注册每个元素的ID来改进,但对于我目前正在解决的问题来说,这太过分了。

我认为使用承诺不会大大简化您的纠缠。但是,您可以使用jQuery事件获得更易于管理的内容。让每个表在完成加载时触发一个事件。让选项卡侦听表,在完成初始化时触发事件,并让对话框侦听这些事件。从绝对意义上讲,这并不比回调简单,但我认为这样会感觉更好——您的各个组件在彼此的业务中所占的比重会更小。@Smcrohan,谢谢您的回复。这种方法的主要问题是,DataTables没有内置的“onCreate”事件或类似事件。我知道如何使用它的fnInitComplete回调,但我必须在创建DataTable时这样做,而不是以后。完美的解决方案是布局我的整个HTML,包括创建最内部对象的JavaScript,最后绑定事件,让每个对象告诉它的父对象它准备好了。如果我知道如何向DataTables添加事件,问题就解决了,因为Tabs已经onCreate了。在创建时给它一个回调函数,手动触发您设计的事件,并让Tabs监听它?避免数据表在开始时需要知道谁在等待它们。
RenderManager('add', 'MyGroup');
$("#TableID").on("init", function() { RenderManager('remove', 'MyGroup'); } );