Je souhaite utiliser les valeurs des attributs sur la relation d'un modèle avec Form::label et Form::text. L'assistant Form a été supprimé de Laravel, donc j'utilise 'Form' => 'Collective\Html\FormFacade' à la place.

Voici la relation dans le modèle Order:

<?php namespace App\Models;

use Illuminate\Database\Eloquent\SoftDeletes;

class Order extends \Eloquent
{
    use SoftDeletes;

    public function account_number()
    {
        return $this->belongsTo('\App\Models\Account_number', 'product_id', 'id');
    }
}

Et voici le modèle Blade avec Form. Le texte dans le account_number <td> affichera:

{"id":4,"user_id":52,"account_type":"alipay","account_no":"xxxxxx","account_name":"xxxxxx","phone":"xxxxxx","created_at":"2017-11-15 14:43:51","updated_at":"2017-11-15 14:43:51","deleted_at":null}
{!! Form::model($order, array('files' => true)) !!}
<table border="1">
<tr>
  <td>{!! Form::label('out_trade_no', 'out_trade_no: ') !!}</td>
  <td>{!! Form::text('out_trade_no')!!}</td>
</tr>
<tr>
  <td>{!! Form::label('account_number', 'account_number: ') !!}</td>
  <td>{!! Form::text('account_number')!!}</td>
</tr>
</table>

Mais je veux afficher les entrées pour chaque attribut account_number séparément, pas comme une chaîne JSON.

J'ai essayé avec:

<tr>
  <td>{!! Form::label('account_number.id', 'account_number: ') !!}</td>
  <td>{!! Form::text('account_number.id')!!}</td>
</tr>

Ou

<tr>
  <td>{!! Form::label('account_number->id', 'account_number: ') !!}</td>
  <td>{!! Form::text('account_number->id')!!}</td>
</tr>

Ou

<tr>
  <td>{!! Form::label('account_number', 'account_number: ') !!}</td>
  <td>{!! Form::text('account_number["id"]')!!}</td>
</tr>

... mais rien de tout cela ne fonctionne. Ils laissent tous ce <td> vide.

7
Kris Roofe 16 nov. 2017 à 05:50

4 réponses

Meilleure réponse

Faisons quelque chose de plus approfondi.

Lors de la génération d'un élément d'entrée de texte, FormBuilder apparaîtra pour la valeur dans la session pour la valeur dans les anciennes données d'entrée, il recherchera dans l'instance de modèle si elle est définie. Sinon, il utilisera simplement vide.
Avant d'obtenir la valeur appropriée, il transformera la clé que nous avons spécifiée, telle que account_number.id, account_number->id, account_number["id"]. Focus sur la fonction transformKey

protected function transformKey($key)
{
    return str_replace(['.', '[]', '[', ']'], ['_', '', '.', ''], $key);
}

Appelons-le avec les clés que vous avez spécifiées une par une:

  1. account_number.id => account_number_id
  2. account_number->id => account_number->id
  3. account_number["id"] => account_number."id"

Ensuite, il divisera la clé en . renvoyant un tableau $keys. Et vérifiez s'il existe un modèle imbriqué avec $keys[0], sinon renvoyez la valeur du modèle maître avec la clé transformée. getFormValue ()

Peu importe qu'il existe ou non un modèle imbriqué, il obtiendra la valeur via data_get ().

De toute évidence, la première clé et la seconde que vous avez spécifiées ne fonctionnent pas. Le troisième account_number."id", il trouvera le modèle imbriqué avec succès mais il ne récupérera pas l'attribut par le chemin $nestedModel->{"id"}. Utilisez plutôt account_number[id], cela fonctionne bien.

<td>{!! Form::text('account_number[id]')!!}</td>
2
Cong Chen 21 nov. 2017 à 15:09

La façon dont vous utilisez le FirmBuilder de LaravelCollective avec la liaison de modèles est incorrecte. Supposons que vous ayez des données dans des ordres comme:

{
id: 1,
....., // some other fields
account_number: {
 "id":4,
 "user_id":52,
 "account_type":"alipay",
 "account_no":"xxxxxx",
 "account_name":"xxxxxx",
 "phone":"xxxxxx",
 "created_at":"2017-11-15 14:43:51",
 "updated_at":"2017-11-15 14:43:51",
 "deleted_at":null
}
}

Donc maintenant, si vous souhaitez afficher account_number id dans textfield, vous pouvez écrire votre générateur de formulaire de cette manière:

{!! Form::model($order, ...) !!} 
    ...
    <tr>
    <td>{!! Form::label('account_number', 'account number: ') !!}</td>
    <td>{!! Form::text('account_number', $order->account_number->id) !!}</td>
    </tr>
    ...
{!! Form::close() !!}

Ou

<td>{!! Form::text('account_number[id]') !!}</td>

Mais dans la deuxième réponse, vous aurez un problème lors de la soumission du formulaire. Parce qu'en plus d'obtenir la valeur que vous vouliez, cette ligne de code renomme également la valeur de vos attributs de nom d'entrée en account_number[id] au lieu de account_number. La meilleure option est donc d'utiliser la première solution. Voici le lien pour la liaison de modèle de formulaire dans LaravelCollective: https://laravelcollective.com / docs / master / html # form-model-binding

1
Yubaraj Shrestha 23 nov. 2017 à 07:39

Pour créer des contrôles d'entrée pour les relations d'un modèle à l'aide des FormBuilder outils fournis par Laravel Collective, utilisez la syntaxe suivante:

{!! Form::model($order, ...) !!} 
    ...
    {!! Form::label('account_number[id]', 'account number: ') !!}
    {!! Form::text('account_number[id]') !!}
    ...
{!! Form::close() !!}

Notez l'absence de guillemets autour de id. L'exemple de la question contient des guillemets autour de l'attribut id du modèle associé, ce qui brise cette magie. Le code ci-dessus rend l'élément d'entrée suivant en utilisant la valeur de l'attribut id sur la relation account_number du modèle Order:

<input name="account_number[id]" type="text" value="4">

Le format affiché dans l'attribut name de l'élément d'entrée permet à PHP d'analyser les données POST sous forme de tableau. Nous pouvons récupérer la valeur soumise à une méthode de contrôleur comme dans cet exemple:

public function save(Request $request) 
{
    $accountNumber = $request->get('account_number'); 

    echo $accountNumber['id']; // '4'
    ...
}

Cette fonctionnalité est importante - FormBuilder génère des éléments d'entrée conçus pour fonctionner avec le regroupement automatique de PHP des données de requête dans des tableaux. Si nous soumettons plusieurs éléments d'entrée sur un formulaire pour la relation d'un modèle, Laravel facilite l'enregistrement du résultat:

public function update(Request $request, $orderId) 
{
    Order::with('account_number')->find($orderId)
        ->fill($request->all())
        ->account_number->fill($request->account_number)
        ->push();
}
3
Cy Rossignol 21 nov. 2017 à 21:05

Après avoir essayé de mettre en œuvre sur mon propre environnement , ma conclusion -

{!! Form::model($order, array('files' => true)) !!}
 <table border="1">
   <tr>
     <td>{!! Form::label('out_trade_no', 'out_trade_no: ') !!}</td>
     <td>{!! Form::text('out_trade_no')!!}</td>
   </tr>
   <tr>
     <td>{!! Form::label('account_number', 'account_number: ') !!}</td>
     <td>{!! Form::text('account_number[id]')!!}</td>
   </tr>
 </table>
1
Sohel0415 26 nov. 2017 à 11:47
47320758