【问题标题】:Strange behavior when returning view with custom Blade directive in Laravel在 Laravel 中使用自定义 Blade 指令返回视图时的奇怪行为
【发布时间】:2017-06-27 23:38:07
【问题描述】:

目前我正在开发一个需要通过自定义 Blade 指令呈现视图的项目。但是,我遇到了一些(很长一段时间内)无法解决的(限制?)错误。

我的自定义 Blade 指令使用树不同的方式输出视图。

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

    // 1
    return view('lw::module.field.field')->render();

    // 2
    return Blade::compileString('{!! view("lw::module.field.field")->render() !!}');

    // 3
    return Blade::compileString('@include("lw::module.field.field")');

});

现场视图:

Get to the choppa!

主视图:

@extends('layout.default')

@section('main_content')

    @lwField()

@endsection

布局文件:

// ... some cool html

@section ('main_content') 

@show

// ... even more cool html

当我分别执行这三个方法时会发生以下情况:

1 return view('lw::module.field.field')->render();

第一次执行时抛出错误:

include(/somepath/storage/framework/views/b30c24f5b8fd420ef1a08edb52e92174e2dfe911.php): failed to open stream: No such file or directory (View: /somepath/resources/views/page/default.blade.php)

这是真的,因为我的缓存文件夹中只有一个视图:

// 5b27802352643346357e49b847d934736c36cd07.php
// The main view with the field view
<?php $__env->startSection('main_content'); ?>

    Get to the choppa!

<?php $__env->stopSection(); ?>

我第二次运行它时,它神奇地起作用了。它将生成其他 3 个文件:

// b30c24f5b8fd420ef1a08edb52e92174e2dfe911.php
// the main view with yielding layout view without field view
<?php $__env->startSection('main_content'); ?>

<?php $__env->stopSection(); ?>

<?php echo $__env->make('layout.default', array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>

// e4cec91e7d4adb5dac5c63e5bfa85ba9a258f664.php
// the layout file
// ...
<?php endforeach; $__env->popLoop(); $loop = $__env->getFirstLoop(); ?>
// ...

// ffd60653d8490007c272c527abef3a5ede092a33.php
// layout view and main view
// ...
<?php $__env->startSection('main_content'); ?>

<?php echo $__env->yieldSection(); ?>
// ...

看起来它生成了两个相同的文件,但一个没有字段视图。

2 return Blade::compileString('{!! view("lw::module.field.field")-&gt;render() !!}');

3 return Blade::compileString('@include("lw::module.field.field")');

这些方法将返回一个空白页面并在缓存中生成两个文件,而不会显示/记录任何错误。

// 5b27802352643346357e49b847d934736c36cd07.php
// Field view
Get to the choppa!

// b30c24f5b8fd420ef1a08edb52e92174e2dfe911.php
// Main view and field view
<?php $__env->startSection('main_content'); ?>

    <?php echo view("lw::module.field.field")->render(); ?>

<?php $__env->stopSection(); ?>

此方法不会生成布局文件。

有没有人知道发生了什么。或许这种行为一点都不奇怪,Blade 应该是这样工作的。

【问题讨论】:

    标签: laravel view render blade directive


    【解决方案1】:

    我一直在做一个需要我做同样事情的项目,问题是当你想渲染另一个视图时,制作一个新的 Blade 指令不是一个好习惯,这是因为缓存,每个 Blade 指令正在被缓存,所以如果你想渲染动态数据,它会给你带来很多问题。

    由于我尝试了很多选项,并且您想渲染另一个视图文件,而不仅仅是将 html 推送到刀片指令,我建议您创建一个新的帮助程序甚至是一个服务,您可以将参数传递给它将返回输出干净 HTML 的渲染函数,这样您就可以确保您的内容始终是动态的并且不会被缓存。

    TL;DR

    示例:

    在你的辅助函数文件中放置:

    function render_my_view() {
        return view(''lw::module.field.field'')->render();
    }
    

    那么在你的刀片文件中你可以使用:

    {!! render_my_view() !!}
    

    【讨论】:

    • 感谢您的提示,将尝试!
    • 感谢您的帮助,它有效。但是我使用自定义 Blade 指令来解析我的文件并检索向用户显示的字段,想想 CMS。我的想法是通过仅在视图中为某些页面声明字段和部分来简化开发人员。现在需要重写我的解析器:(:)。还是非常感谢!
    • 我还使用 Blade 指令来检索控制器传递给主视图的get_defined_vars()。由于视图中不再发生渲染,我必须找到另一种方法来解决这个问题。有什么建议?我考虑使用Blade::compose
    • 您可以将变量传递给辅助函数:例如:{!! render_my_view(get_defined_vars()) !!}
    • 我知道,我只是不想让开发人员每次都这样做。它需要是自动的。我使用 View::composer() 修复了它 bij
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-19
    • 2019-08-13
    • 2015-09-07
    相关资源
    最近更新 更多