Pergunta

Estou usando o Laravel Framework 4.1.30.

Como você passa dados de um modelo para outro sem passar por rota ou controlador?

Especificidades:Recebi um modelo de blade "Principal" que é estendido por um modelo de blade "Sign-in".Meu objetivo é colocar quaisquer erros que apareçam no modelo "Sign-in" e exibi-los em uma seção de rodapé do modelo "Principal".

Meus códigos para o modelo principal dentro da tag "body" são os seguintes (observe que existem alguns códigos para formatar minha visualização):

<!-- Serving as Header -->
@include('layout.navigation')

<!-- Serving as left content/status displays -->
@include('layout.frameleft') 

<!-- Serving as right content/entry point -->
@yield('content')

<!-- Serving as Error Notification/footer -->
@if (Session::has('global'))
      {{ Session::get('global') }}
@endif

O modelo blade que chama Main é codificado assim:

@extends('layout.main')

@section('content')

    ... more code here / input fields ...

    {{ $errors->first('email')}}

    ... more code here / input fields ...

@stop

Pelo que entendi (bastante novo no Laravel), o conteúdo deve ser lido primeiro, antes da sessão ser exibida globalmente.

Eu esperava que uma simples variável passando entre os modelos fosse suficiente (se existir) para resolver o problema.Desejo passar o valor do erro do conteúdo de volta para o modelo principal na parte da seção de rodapé sem voltar ao controlador.

Estou ciente de que existem soluções alternativas, como em vez de esperar que o controlador envie os erros para o modelo, eu poderia passar os erros diretamente para a variável global por meio da sessão (ou para o layout) do Controlador.Atualmente, o seguinte código de trabalho é o que eu implementei, mas estou apenas me perguntando o que aconteceria se os dados já tivessem sido passados ​​para o modelo.

public function postSignin() {

        $validator = Validator::make(Input::all(),
            array(
                    'email'     => 'required|email',
                    'password'  => 'required'
            )
        ); 

        if ($validator->fails()) {

            $errors = $validator->errors();
            $formErrors = 'Errors: ';

            foreach($errors->all() as $error ) {
                $formErrors .= sprintf("%s", $error);
            }

            return Redirect::route('account-sign-in')
                ->withErrors($validator)
                ->withInput()
                ->with('global',$formErrors);

        } else {

        ...more codes here...

O motivo pelo qual estou fazendo isso é que originalmente meu código no controlador é exatamente assim.

        if ($validator->fails()) {

           return Redirect::route('account-sign-in')
              ->withErrors($validator)
              ->withInput();

Agora parece tão grande.Acho que se eu pudesse aliviar o controlador com um loop, meu programa seria mais eficiente.

Foi útil?

Solução

De Documentação Laravel (ênfase deles):

Entretanto, observe que não precisamos vincular explicitamente as mensagens de erro à visualização em nossa rota GET.Isso ocorre porque o Laravel sempre verificará se há erros nos dados da sessão e os vinculará automaticamente à visualização, se estiverem disponíveis. Então, é importante ressaltar que um $errors variável estará sempre disponível em todas as suas visualizações, em todas as solicitações, permitindo assumir convenientemente que a variável $errors está sempre definida e pode ser usada com segurança.O $errors variável será uma instância de MessageBag.

Porque o Laravel Redirect... withErrors() método faz isso, você não precisa adicionar os erros à Sessão novamente manualmente.Em vez de verificar if (Session::has('global')), basta fazer isso:

<!-- Serving as Error Notification/footer -->
@foreach ($errors as $error)
    <p>{{ $error }}</p>
@endforeach

Isso deve funcionar embora está no layout e não na visão real, porque a vinculação que se aplica errors dentro do modelo também os aplica fora dele.

Se não houver erros, o Laravel irá simplesmente pular esse bloco.Se houver erros, eles terão sido automaticamente vinculados ao $errors variável e será renderizado conforme o esperado.

Outras dicas

Eu estava escrevendo originalmente uma resposta que recomendava Ver compositores, mas reli a pergunta e acredito que o que você precisa fazer é abstrair a validação do formulário para uma classe 'formulário':

interface FormInterface {
    public function isValid($input);
    public function errors();
}

A ideia básica que tirei da sua pergunta é que você deseja que seu controlador seja parecido com isto:

public function postSignIn()
{
    if(!$this->_signinForm->isValid(Input::all())) {
        return Redirect::route('account-sign-in')
            ->withErrors($this->_signinForm->errors())
            ->withInput()
        ;
    }

    // Non-error logic branch
}

Sua classe de formulário conterá basicamente uma referência ao objeto validador.Todos isValid método deve fazer é basicamente chamar passes() no validador e todos os error método simplesmente retornará os resultados da chamada errors() no validador.

Sinceramente, não tenho ideia de por que você está combinando todas as mensagens de erro em uma única variável. Presumo que seja porque você deseja que todas elas sejam exibidas no mesmo lugar.Se for esse o caso e é assim que você deseja que os erros funcionem, você pode incorporar isso ao seu formulário errors método.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top