ホームページ >php教程 >php手册 >Yii2的相关学习记录,alert等美化、confirm异步、session中的flash及小部件的使用(六) - 漫游云巅

Yii2的相关学习记录,alert等美化、confirm异步、session中的flash及小部件的使用(六) - 漫游云巅

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBオリジナル
2016-05-20 11:54:081915ブラウズ

呃,系统自带的alert、confirm等弹出框实在是难看,作为一个颜控,这能忍?

这里我用的是kartik-v/yii2-dialog,这个是基于bootstrap3-dialog这个来做了一些常用alert、confirm和dialog的小部件封装,当然了,本质上还是bootstrap3-dialog,可以用原生的方法,原生方法的用法点这里,而bootstrap3-dialog又是基于bootstrap3的modals做的封装。嗯,基本关系就是这样。在搜索这个相关知识时,经常会看到有人提到bootbox,这个同样是流行的一个美化插件,基本原理类似,用法稍微不同,在packagist搜索yii2 bootbox会发现也有人为Yii2做了集成(或者自己集成也行,后面会讲到),同样值得推荐。

按照说明安装,最好是按照github的说明,因为最新的一般都会在这里先更新。composer中要用@dev。可以看这里的说明,如果不成功,先composer self-update,再试下,当初安装时也是各种报错不行,后来突然就好了。稍微注意的是confirm,dialog调用时要求必须写回调,否则就报错。

还是蛮漂亮的。但是像是Yii框架Gridview自带的confirm(像是删除按钮),点击时还是原生的,因为它的源码就是用的confirm命令,好在Yii框架提供了方法,可以让我们覆盖confirm方法。具体可如下操作:

1、我们可以先看下在vendor/yiisoft/yii2/assets/yii.js文件中的confirm方法:注释中就可以看到,可以用yii.confirm来重写此设置。

 <span style="color: #008000;">/*</span><span style="color: #008000;">*
    * Displays a confirmation dialog.
    * The default implementation simply displays a js confirmation dialog.
    * You may override this by setting `yii.confirm`.
    * @param message the confirmation message.
    * @param ok a callback to be called when the user confirms the message
    * @param cancel a callback to be called when the user cancels the confirmation
    </span><span style="color: #008000;">*/</span><span style="color: #000000;">
    confirm</span>: <span style="color: #0000ff;">function</span> (message, ok,<span style="color: #000000;"> cancel) {
        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (confirm(message)) {
            </span>!ok ||<span style="color: #000000;"> ok();
        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
            </span>!cancel ||<span style="color: #000000;"> cancel();
        }
    }</span>,

2、那我们就重写,可以在backend/web/js中新建confirm.js文件,然后重新,可参照此文章,这是设置bootbox的,而且版本有点过时,不过下方的评论有最新方法。而我们的设置与此原理是一致的,只不过是改成kartik-v/yii2-dialog所需求的参数样式:

yii.confirm = <span style="color: #0000ff;">function</span> (message, ok,<span style="color: #000000;"> cancel) {
    krajeeDialog</span>.confirm(message,<span style="color: #0000ff;">function</span><span style="color: #000000;">(data){
        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (data) {
            </span>!ok ||<span style="color: #000000;"> ok();
        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
            </span>!cancel ||<span style="color: #000000;"> cancel();
        }
    });
    </span><span style="color: #008000;">//</span><span style="color: #008000;"> confirm will always return false on the first call
    // to cancel click handler</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;
}</span>

3、我们需要注册此js,可以在backend/assets/Appasset.php中添加上方的js文件:

<span style="color: #0000ff;">class</span> AppAsset <span style="color: #0000ff;">extends</span><span style="color: #000000;"> AssetBundle
{
    </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$basePath</span> = '@webroot'<span style="color: #000000;">;
    </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$baseUrl</span> = '@web'<span style="color: #000000;">;
    </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$css</span> =<span style="color: #000000;"> [
        </span>'css/site.css',<span style="color: #000000;">
    ];
    </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$js</span> =<span style="color: #000000;"> [
        </span>'js/confirm.js',<span style="color: #008000;">//</span><span style="color: #008000;">就是这里了</span>
<span style="color: #000000;">    ];
    </span><span style="color: #0000ff;">public</span> <span style="color: #800080;">$depends</span> =<span style="color: #000000;"> [
        </span>'yii\web\YiiAsset',
        'yii\bootstrap\BootstrapAsset',<span style="color: #000000;">
    ];
}</span>

这样一来,在点击删除按钮便会发现可以调用了:

由于我们用的是kartik-GridView,它的两个功能展示全部记录和导出csv等的提示,都是用的原生的confirm,强迫症的我们能忍吗?好吧,我忍了,这里只给出改的思路,尤其是只懂基础js的我来说,先把时间放在其它地方吧。

在改之前,首先我们需要明确kartik-v/yii2-dialog的confirm(bootbox同样)和原生confirm的不同。原生confirm是同步的,而kartik-v/yii2-dialog的confirm方法是异步回调的。这导致原生的confirm可以直接这样写:

<span style="color: #0000ff;">function</span><span style="color: #000000;"> abc(){
    </span><span style="color: #0000ff;">return</span> window.confirm('123');<span style="color: #008000;">//</span><span style="color: #008000;">confirm点击确认返回true,取消返回false,不点击就等着用户点击    </span>
<span style="color: #000000;">}
</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(abc()){
    alert(</span>'456');<span style="color: #008000;">//</span><span style="color: #008000;">点击是,会弹出alert弹窗</span>
}

而如果你用kartik-v/yii2-dialog的confirm也这样写,则永远不会弹窗,因为是异步回调的,不会去等你点击。

<span style="color: #0000ff;">function</span><span style="color: #000000;"> abc(){
    krajeeDialog.confirm(</span>'123',<span style="color: #0000ff;">function</span><span style="color: #000000;">(result){
        </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(result){
            </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;
        }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{
            </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;
        }
    });
}
</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(abc()){
    alert(</span>'456');<span style="color: #008000;">//</span><span style="color: #008000;">由于是异步回调,所以不管点不点都不会弹窗</span>
}

可能有人会想(比如我)这样写行不行?不行,不支持这样的写法,bootstrap3-dialog中这样写返回的是窗口有没有open。

<span style="color: #0000ff;">if</span>(krajeeDialog.confirm('123',<span style="color: #0000ff;">function</span><span style="color: #000000;">(result){}){
    </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;
}</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{
    </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #000000;">;      
}</span>

所以要想在kartik-v/yii2-dialog的confirm中执行alert,只能将alert放在回调函数中:

<span style="color: #0000ff;">function</span><span style="color: #000000;"> abc(){
    krajeeDialog.confirm(</span>'123',<span style="color: #0000ff;">function</span><span style="color: #000000;">(result){
        </span><span style="color: #0000ff;">if</span><span style="color: #000000;">(result){
            alert(</span>'456'<span style="color: #000000;">);
        }</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{
           </span><span style="color: #008000;">//</span><span style="color: #008000;">do something</span>
<span style="color: #000000;">        }
    });
}</span>

 以上的不同,再加上是在vendor中修改有违原则啊(拿出来很费劲,又是继承什么的,而导出csv的js没找到类似yii.js那样覆盖的方法,只能重新写引入什么的),也是我不想改源码的原因。坑爹。好吧,下面继续说怎么改:

1、{toggleData}显示全部记录,它的调用confirm是在vendor/kartik-v/yii2-grid/GridView.php中的getToggleDataScript方法,我们修改return就可以:

<span style="color: #800080;">$url</span>=Url::<span style="color: #008080;">current</span>([<span style="color: #800080;">$this</span>->_toggleDataKey => <span style="color: #800080;">$tag</span>]);<span style="color: #008000;">//</span><span style="color: #008000;">先定义需要跳转的url</span>
<span style="color: #0000ff;">return</span> "\$('#{<span style="color: #800080;">$this</span>->_toggleButtonId}').on('{<span style="color: #800080;">$event</span><span style="color: #000000;">}',function(e){
    e.preventDefault();//先阻止点击事件
    krajeeDialog.confirm('{</span><span style="color: #800080;">$msg</span><span style="color: #000000;">}',function(data){
        if (data) {
            window.location.href='{</span><span style="color: #800080;">$url</span><span style="color: #000000;">}';//点击是则跳转
        }
    });
    //下面这条是原来的方法
    // if(!window.confirm('{</span><span style="color: #800080;">$msg</span><span style="color: #000000;">}')){e.preventDefault();}
});</span>";

2、{export}中的导出提示,是在vendor/kartik-v/yii2-grid/assets/js/kv-grid-export.js中:这个就麻烦了,感觉需要重写关联的notify方法和listenClick方法。谁写完了,麻烦告诉一声吧。

kvConfirm: <span style="color: #0000ff;">function</span><span style="color: #000000;"> (msg) {             
    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
        </span><span style="color: #0000ff;">return</span> window.confirm(msg);<span style="color: #008000;">//</span><span style="color: #008000;">调的这个</span>
<span style="color: #000000;">    }
    </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (err) {
        </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">;
    }
}</span>

上面就这样吧,下面说下session中的flash,我们一般创建完成等操作时,需要给点提示是完成了还是怎么着。在Yii中有自带flash方法来实现,可点击这里查看,其实在adminLTE这个后台框架中已集成了Alert小部件,我们可以在backend/views/layout/content.php中发现此小部件的调用= Alert::widget() ?>,这是我们只需要在controller中添加setFlash方法,那么就能在view中接收到:

  <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span><span style="color: #000000;"> actionCreate()
    {
        </span><span style="color: #800080;">$model</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> User();

        </span><span style="color: #0000ff;">if</span> (<span style="color: #800080;">$model</span>->load(Yii::<span style="color: #800080;">$app</span>->request->post()) && <span style="color: #800080;">$model</span>-><span style="color: #000000;">save()) {
            </span><span style="color: #800080;">$session</span> = Yii::<span style="color: #800080;">$app</span>->session;<span style="color: #008000;">//</span><span style="color: #008000;">session</span>
            <span style="color: #800080;">$session</span>->setFlash('success', '创建成功');<span style="color: #008000;">//</span><span style="color: #008000;">添加flash</span>
            <span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->redirect(['index'<span style="color: #000000;">]);
        } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
            </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$this</span>->render('create',<span style="color: #000000;"> [
                </span>'model' => <span style="color: #800080;">$model</span>,<span style="color: #000000;">
            ]);
        }
    }</span>

捕捉到的:(adminLTE的alert样式颜色就是这么深,而Yii框架自带的颜色虽然浅,但是与此后台框架的颜色也不搭配)

进一步扩展就是,如果是成功的提示,那我5s后可以隐藏,那可以这样设置,在backend/views/layout/content.php中添加下面渐隐的js代码

<?php <span style="color: #008000;">//<span style="color: #008000;">这是一段,在显示</span>
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。