Laravel 扩展刀片模板 - $errors 集合中的错误

Posted

技术标签:

【中文标题】Laravel 扩展刀片模板 - $errors 集合中的错误【英文标题】:Laravel Extending Blade Templates - error in $errors collection 【发布时间】:2017-04-03 16:59:13 【问题描述】:

我正在使用 Laravel 5.3。我的第一个 Laravel 项目/学习经历 在我的刀片文件中,我使用以下 sn-p 在 PUT 或 POST 请求后显示字段下方的错误。

在这种情况下,数据库字段称为 firstName

        @if ($errors->has('firstName'))
            <span class="help-block">
                <strong> $errors->first('firstName') </strong>
            </span>
        @endif

现在因为我有很多字段,所以我一直在为每个字段重复这个块。我在 Blade 模板(扩展 Blade 部分)上查找了 Laravel 文档,并认为我可以在 AppServiceProvider 类(AppServiceProvider .php)中执行以下操作

public function boot()

    //
    Blade::directive('showIfError', function($fieldName) 
        if ($errors->has('$fieldName')) 
            echo "<span class='help-block'>
            <strong> $errors->first('$fieldName') </strong>
            </span>";
        
    );

然后使用

@showIfError('firstName')

但没有运气...我收到错误“未定义的变量:错误”

在此视图文件中似乎无法访问 Laravel 错误集合。

感谢任何帮助。谢谢。

【问题讨论】:

能否请您包括您想要实现的目标? 我不想复制并粘贴表单中每个字段的 if (errors...) 块。相反,我想要一个像 @showIfError('fieldName') 这样的宏/刀片模板,最终输出将像上面给出的 span 块一样呈现。 我发现视图缓存干扰了输出。如果我删除存储(缓存)文件夹中的所有文件,我可以使用 session('errors') 让它工作,但它只能工作一次!再次提交相同错误的表单不会产生任何输出!因此,我无法完全测试任何答案是否有效:-( 此外 Blade::directive 函数不接受 2 个参数。 【参考方案1】:

这是迟到的回复,但希望它会帮助另一个来的人。自定义刀片指令应该返回一个字符串 php 代码,该代码将在呈现模板时进行评估。因为$errors 变量仅在做出响应时可用,所以尝试在指令中评估它是行不通的。解决办法是这样的:

 // custom blade directive to render the error block if input has error
 // put this inside your service provider's boot method

     \Blade::directive('errorBlock', function ($input) 
            return
                '<?php if($errors->has('.$input.')):?>
                    <div class=\'form-control-feedback\'>
                        <i class=\'icon-cancel-circle2\'></i>
                    </div>
                    <span class=\'help-block\'>
                            <strong><?php echo $errors->first('.$input.') ?></strong>
                    </span>
                 <?php endif;?>';
        );

【讨论】:

【参考方案2】:

事情是 $errors 在关闭时无法访问。此外,您不能传递整个对象,因为指令闭包只接受字符串。使用简单数据,您可以先implode(),然后再使用explode(),但不能使用对象或集合。

您可以做的是在闭包内手动创建$errors

我已经测试过了,它按预期工作:

Blade::directive('showIfError', function($fieldName) 
    $errors = session('errors');

    if ($errors->has($fieldName)) 
        return "<span class='help-block'>".$errors->first($fieldName)."</span>";
    
);

【讨论】:

【参考方案3】:

问题在于 $errors 变量仅在视图中可用。如果您查看共享变量 (https://github.com/laravel/framework/blob/5.0/src/Illuminate/View/Middleware/ShareErrorsFromSession.php) 的中间件,您会看到它存储在会话中。

所以你可以按如下方式访问它:

$errors = session()->get('errors');

请注意,在您的示例中,您确实还有其他一些问题; $fieldName 变量不应该用引号引起来。例如:

public function boot() 
Blade::directive('showIfError', function($fieldName) 
$errors = session()->get('errors');
 if ($errors->has($fieldName)) 
      echo "<span class='help-block'> <strong>". $errors->first($fieldName). "</strong> </span>";
  
);

【讨论】:

【参考方案4】:

我终于在我的视图中编写了一个 PHP 函数,并使用各种字段名称调用它。 我希望这是一个好方法。不确定实现此功能的最佳方法是什么。

function showIfError($fieldName)

    $errors=session('errors');
    if ( count( $errors)>0) 
        if (session('errors')->has($fieldName)) 
            $msg=$errors->first($fieldName);
            echo '<span class="help-block">
                    <strong>'. $msg.' </strong>
                </span>';
        
    


【讨论】:

以上是关于Laravel 扩展刀片模板 - $errors 集合中的错误的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 刀片模板扩展了两种不同的布局

如何从 Laravel5 中的刀片模板传递扩展主模板中的变量?

Laravel Blade:@extend 一个(已经扩展的)子刀片?

Laravel 8重定向回来,消息在刀片模板中不起作用

Laravel 刀片模板停止重新加载主布局

使用刀片布局来扩展模板