Yii renderpartial (proccessoutput = true) 避免重复的 js 请求 [英] Yii renderpartial (proccessoutput = true) Avoid Duplicate js request

查看:13
本文介绍了Yii renderpartial (proccessoutput = true) 避免重复的 js 请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个使用 ajaxRequest 的站点,当我单击一个链接时,它将使用 ajaxRequest 加载.例如,当我加载用户/登录名 UserController actionLogin 时,我 将带有 processOUTput 的视图渲染为 true,因此将生成该视图中所需的 js,但是如果我在里面有 clientScriptRegister那个带有事件的视图,如何避免根据 ajaxRequest 生成两次或多次的 scriptRegistered?我试过 Yii::app()->clientScript->isSCRiptRegistered('scriptId') 来检查脚本是否已经注册,但似乎如果你使用 ajaxRequest,结果是始终为假,因为只有在渲染完成后才会为真.

Im creating a site who works with ajaxRequest, when I click a link, it will load using ajaxRequest. When I load for example user/login UserController actionLogin, I renderPartial the view with processOUtput to true so the js needed inside that view will be generated, however if I have clientScriptRegister inside that view with events, how can I avoid to generate the scriptRegistered twice or multiple depending on the ajaxRequest? I have tried Yii::app()->clientScript->isSCriptRegistered('scriptId') to check if the script is already registered but it seems that if you used ajaxRequest, the result is always false because it will only be true after the render is finished.

控制器代码

if (Yii::app()->request->isAjaxRequest)
{
   $this->renderPartial('view',array('model'=>$model),false,true);
}

查看代码

if (!Yii::app()->clientScript->isScriptregistered("view-script"))
   Yii::app()->clientScript->registerScript("view-script","
      $('.link').live('click',function(){
         alert('test');
     })
");

如果我第一次请求控制器,它工作得很好(警报 1 次)但是如果我再次请求同一个控制器而不刷新我的页面并且只使用 ajaxRequest,如果你点击它,警报将输出两次(因为即使您已经注册过它,它也会继续生成)

If I request for the controller for the first time, it works perfectly (alert 1 time) but if I request again for that same controller without refreshing my page and just using ajaxRequest, the alert will output twice if you click it (because it keeps on generating eventhough you already registered it once)

如果您在具有 jquery 功能的视图中有 CActiveForm,这也是一样的.. 每次 renderPartial 时都会调用 corescript yiiactiveform.

This is the same if you have CActiveForm inside the view with jquery functionality.. the corescript yiiactiveform will be called everytime you renderPartial.

推荐答案

避免包含两次核心脚本

如果您的脚本已通过较早的请求包含在内,请使用此选项以避免再次包含它们:

To avoid including core scripts twice

If your scripts have already been included through an earlier request, use this to avoid including them again:

// For jQuery core, Yii switches between the human-readable and minified
// versions based on DEBUG status; so make sure to catch both of them
Yii::app()->clientScript->scriptMap['jquery.js'] = false;
Yii::app()->clientScript->scriptMap['jquery.min.js'] = false;

如果您的视图既独立呈现又作为 HTML 片段包含在 AJAX 中,您可以将其包装在 if (Yii::app()->request->isAjaxRequest)覆盖所有基础.

If you have views that are being rendered both independently and as HTML fragments to be included with AJAX, you can wrap this inside if (Yii::app()->request->isAjaxRequest) to cover all bases.

还有可能阻止脚本在客户端被包含两次.这不是直接支持的,而且稍微有点麻烦,但在实践中它运行良好,并且不需要您在服务器端知道客户端正在发生什么(即已经包含哪些脚本).

There's also the possibility of preventing scripts from being included twice on the client side. This is not directly supported and slightly more cumbersome, but in practice it works fine and it does not require you to know on the server side what's going on at the client side (i.e. which scripts have been already included).

这个想法是从服务器获取 HTML 并简单地去除 <script> 标签和正则表达式替换.重要的一点是,您可以检测 jQuery 核心脚本和插件是否已经加载(因为它们在其上创建了 $ 或属性)并有条件地执行此操作:

The idea is to get the HTML from the server and simply strip out the <script> tags with regular expression replace. The important point is you can detect if jQuery core scripts and plugins have already been loaded (because they create $ or properties on it) and do this conditionally:

function stripExistingScripts(html) {
    var map = {
        "jquery.js": "$",
        "jquery.min.js": "$",
        "jquery-ui.min.js": "$.ui",
        "jquery.yiiactiveform.js": "$.fn.yiiactiveform",
        "jquery.yiigridview.js": "$.fn.yiiGridView",
        "jquery.ba-bbq.js": "$.bbq"
    };

    for (var scriptName in map) {
        var target = map[scriptName];
        if (isDefined(target)) {
            var regexp = new RegExp('<script.*src=".*' +
                                    scriptName.replace('.', '\.') +
                                    '".*</script>', 'i');
            html = html.replace(regexp, '');
        }
    }

    return html;
}

如果已经包含了相应的脚本,就会有一个文件名和对象的映射;通过此函数传递传入的 HTML,它将检查并删除与先前加载的脚本相对应的

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆