【问题标题】:JQuery Sortable initialization after Ajax Update using yii-jui使用 yii-jui 进行 Ajax 更新后的 JQuery 可排序初始化
【发布时间】:2017-02-17 09:20:23
【问题描述】:

我遇到了一个问题,正在寻找在不改变 Yii2 框架的情况下解决它的最佳方法。

我有一个页面,其中包含可以排序的元素。我正在使用 yii-jui 可排序小部件,在初始视图后一切正常。

在某些情况下,我需要使用每个 ajax 的所有元素来更新内容。这也有效。

问题是,当我在 ajax 调用后更新内容时,可排序元素及其容器的 jquery 初始化会丢失。

在构建初始视图时,yii-jui 扩展将用于初始化可排序元素的 javascript 放置在 Javascript 块中的文档就绪函数中。正如我已经说过的,这在第一个视图中效果很好。但是,当我更新内容时,初始化会丢失,并且不知何故我需要再次运行 javascript 初始化。我无法执行此操作,因为未触发文档就绪功能。

一种可能的解决方案是将可排序元素的所有 JS 初始化放入一个单独的函数中,并在第一个视图之后以及 ajax 更新之后显式调用它。困难在于我看不出用 yii-jui 小部件来执行此操作,因为它将所有初始化(事件和选项)作为单个调用放在 on-document-ready 函数中。

我考虑过以下几点

  • 在 yii-jui 小部件中添加一个选项来放置初始化步骤 变成一个 JS 函数
  • 使用视图事件挂钩来操作 JS 在构建 HTML 之前进行捆绑/资产设置,这样我就可以 创建我需要的功能
  • 不要在 yii-jui 小部件,但我自己编写了一个单独的初始化脚本。

关于如何最好地进行的任何想法?

感谢您的任何意见

安迪·波特

【问题讨论】:

    标签: jquery ajax yii2 jquery-ui-sortable


    【解决方案1】:

    由于您的视图中已经有 jquery,您需要防止 yii2 再次使用 ajax 请求加载它(您也可以考虑一些其他文件,例如 yii.js):

    $view->on(View::EVENT_END_PAGE, function($event){ 
    
        $positions = $event->sender->jsFiles;
        foreach($positions as $position => $js){
            $new = array_filter($js, 
            function($item){
                return !preg_match('/jquery(\.min)?\.js|yii(\.min)?\.js/i', $item);
            });
            $event->sender->jsFiles[$position] = $new;
        }
    
    });
    

    您可以根据需要过滤任意数量的 js 文件,方法是将它们添加到 preg_match 模式中。

    【讨论】:

      【解决方案2】:

      我找到了解决方案。

      通过“挂钩”到 View EVENT_END_PAGE 事件中,我能够更改生成的 Javascript 代码并将其放入函数中。

      public function actionIndex()
      {
          $this->layout = 'main-full';
          Yii::$app->getUser()->setReturnUrl(Yii::$app->request->getUrl());
      
          $this->getView()->on(View::EVENT_END_PAGE, [$this, 'jsAsFunction']);
      
          return $this->render('index', [
              'board' => $this->currentBoard,
              'columnHtml' => $this->getColumnHtml(),
          ]);
      }
      
      public function jsAsFunction($event)
      {
          $event->sender->js[View::POS_HEAD] = ['var initializeBoard;'];
          $event->sender->js[View::POS_HEAD] = ['var longPollingTimeout = ' . self::LONG_POLLING_TIMEOUT . ';'];
          $event->sender->js[View::POS_READY] = array_merge(
              ['initializeBoard = function() {'],
              $event->sender->js[View::POS_READY],
              ['}'],
              ['initializeBoard();']
          );
      
          return true;
      }
      

      当视图生成内联 Javascript 时,所有数组元素都内爆在一起。所以我只是将代码包围在函数声明中。之后就可以使用了。

      重要

      • 函数必须在声明后显式调用
      • 为了使该功能在范围之外可用 jQuery(document).ready 必须将其分配给具有 已在全局范围内声明。因此,前两个任务 生成到<HEAD> 区域。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多