使用yii-jui进行Ajax更新后的JQuery Sortable初始化

时间:2016-10-08 13:42:19

标签: jquery ajax yii2 jquery-ui-sortable

我遇到了问题,正在寻找解决问题的最佳方法,而不改变Yii2框架。

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

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

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

在构建初始视图时,yii-jui扩展将javascript用于在文档就绪函数内的Javascript块中初始化Sortable元素。正如我已经说过的,这在第一个视图中工作正常。但是,当我更新内容时,初始化将丢失,并且我需要再次运行javascript初始化。我不能这样做,因为没有触发文档就绪函数。

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

我考虑过以下

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

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

感谢任何输入

安迪波特

2 个答案:

答案 0 :(得分: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模式中。

答案 1 :(得分:0)

我找到了解决方案。

通过“挂钩”查看 EVENT_END_PAGE 事件,我可以更改生成的Javascript代码并将其放入函数中。

switch weatherType {
case .Cloudy(_):
    print("It is cloudy. I ignore the coverage.")
...
}

switch weatherType {
case .Cloudy(let coverage):
    print("It is cloudy. Coverage is \(coverage).")
...
}

switch weatherType {
case .Cloudy(let coverage) where coverage > 80:
    print("It is very cloudy.")
case .Cloudy(let coverage) where coverage < 20:
    print("It is slightly cloudy.")
case .Cloudy(_):
    print("It is cloudy.")
...
}

当View生成内联Javascript时,所有数组元素都会内爆。所以我只是在函数声明中包含了代码。之后,它将在稍后提供。

重要

  • 该函数必须在声明
  • 后显式调用
  • 为了使功能在范围之外可用 jQuery(document).ready它必须分配给一个具有的变量 已被宣布具有全球范围。因此,前两个任务即 生成到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; } 区域。