Laravel 中使用自定义 Blade 指令返回视图时的奇怪行为

Strange behavior when returning view with custom Blade directive in Laravel

目前我正在做一个需要通过自定义 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")->render() !!}');

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

这些方法将 return 空白页面并在缓存中生成两个文件,不会 showing/logging 任何错误。

// 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 应该如何工作。

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

因为我已经尝试了很多选项并且你想要渲染另一个视图文件而不是仅仅将 html 推到 blade 指令,我建议你制作一个新的助手甚至是服务,你可以在那里传递参数,它将 return 输出干净的渲染函数 HTML 所以这样你可以确保你的内容将始终是动态的并且不会被缓存。

TL;DR

示例:

在您的辅助函数文件中放入:

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

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

{!! render_my_view() !!}