如何在laravel刀片上进行一次性推动

ma.*_*ian 10 php laravel blade

我正在尝试使用类似于以下(widget.blade.php)的Laravel刀片创建HTML小部件:

@push('scripts')
   <script src="{{ asset('js/foo.js') }}"></script>
   <script>
   ...
   </script>
@endpush
@push('styles')
   <link href="{{ asset('css/bar.css') }}" rel="stylesheet">
@endpush
<div>
... HTML contents
</div>
Run Code Online (Sandbox Code Playgroud)

我在其他刀片中使用小部件,如:

<div>
  ... 
  @include('widget')
</div>
<div>
  ... 
  @include('widget')
</div>
Run Code Online (Sandbox Code Playgroud)

问题是当我在页面中多次使用窗口小部件时,"脚本"和"样式"重复多次.

如何防止Laravel多次推送"脚本"和"样式"?

ma.*_*ian 13

在下面的回答中,我假设您熟悉 Blade扩展.该方法已在Laravel 5.2和5.3上进行了测试(参见下面的注释).

在测试了Ismail RBOUH的答案后(请阅读它),该解决方案似乎有两个问题:

1- $ isDisplayed变量与其他包含的小部件不在同一范围内,因此每个@include将其脚本推送到堆栈.结果我将其更改为:

Blade::directive('pushonce', function ($expression) {
    $isDisplayed = '__pushonce_'.trim(substr($expression, 2, -2));
    return "<?php if(!isset(\$__env->{$isDisplayed})): \$__env->{$isDisplayed} = true; \$__env->startPush{$expression}; ?>";
});
Blade::directive('endpushonce', function ($expression) {
    return '<?php $__env->stopPush(); endif; ?>';
});
Run Code Online (Sandbox Code Playgroud)

2-解决方案将@pushonce的使用限制为一个小部件.即,在2个或更多小部件(widget1.blade.php,widget2.blade.php,...)的情况下,它阻止推送其他小部件脚本.因此,我使用以下代码将域添加到@pushonce:

Blade::directive('pushonce', function ($expression) {
    $domain = explode(':', trim(substr($expression, 2, -2)));
    $push_name = $domain[0];
    $push_sub = $domain[1];
    $isDisplayed = '__pushonce_'.$push_name.'_'.$push_sub;
    return "<?php if(!isset(\$__env->{$isDisplayed})): \$__env->{$isDisplayed} = true; \$__env->startPush('{$push_name}'); ?>";
});
Blade::directive('endpushonce', function ($expression) {
    return '<?php $__env->stopPush(); endif; ?>';
});
Run Code Online (Sandbox Code Playgroud)

用法:

widget1.blade.php

@pushonce('scripts:widget1')
   <script src="{{ asset('js/foo.js') }}"></script>
   <script>
   ...
   </script>
@endpushonce
Run Code Online (Sandbox Code Playgroud)

widget2.blade.php

@pushonce('scripts:widget2')
   <script src="{{ asset('js/bar.js') }}"></script>
   <script>
   ...
   </script>
@endpushonce
Run Code Online (Sandbox Code Playgroud)

L 5.3的注意事项: 更改以下行:

$domain = explode(':', trim(substr($expression, 2, -2)));
Run Code Online (Sandbox Code Playgroud)

$domain = explode(':', trim(substr($expression, 1, -1)));
Run Code Online (Sandbox Code Playgroud)

  • 最好将“@endpushonce”指令代码复制到您的答案中。否则有点混乱。 (2认同)

小智 11

这对我有用。

@once
    @push('page_scripts')
        <script type="text/javascript">
           
        </script>
    @endpush
@endonce
Run Code Online (Sandbox Code Playgroud)


Ism*_*OUH 6

一种解决方案是通过创建如下指令来扩展Bladepushonce

Blade::directive('pushonce', function ($expression) {

    $isDisplayed = '$__pushonce_'.trim(substr($expression, 2, -2));

    return "<?php if(!isset({$isDisplayed})): {$isDisplayed} = true; \$__env->startPush{$expression}; ?>";
});

Blade::directive('endpushonce', function ($expression) {

    return '<?php $__env->stopPush(); endif; ?>';
});
Run Code Online (Sandbox Code Playgroud)

它必须添加到AppServiceProvider boot方法中。

用法:

@pushonce('scripts')
   <script src="{{ asset('js/foo.js') }}"></script>
   <script>
   ...
   </script>
@endpushonce

@pushonce('styles')
   <script src="{{ asset('js/foo.js') }}"></script>
   <script>
   ...
   </script>
@endpushonce
Run Code Online (Sandbox Code Playgroud)

请测试一下,如果有帮助,请告诉我。