2017-10-05 2 views
0

J'ai une vue qui a été échafaudée à partir d'un modèle. Je dois récupérer les valeurs des balises d'aide "editfor", faire un tas de calculs, puis renvoyer les résultats (multiples) à la vue. J'ai créé un petit exemple pour clarifier.Passer le contenu du formulaire à un contrôleur, faire des calculs, puis renvoyer plusieurs résultats

public class OpticalcTestViewModel 
{ 
    public double OD_Sphere { get; set; } 
    public double OD_Cylinder { get; set; } 
    public int Axis { get; set; } 
} 

Ce qui crée cet échafaudage:

@using (Html.BeginForm()) 
{ 
@Html.AntiForgeryToken() 

<div class="form-horizontal"> 
    <h4>OpticalcTestViewModel</h4> 
    <hr /> 
    @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
    <div class="form-group"> 
     @Html.LabelFor(model => model.OD_Sphere, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.OD_Sphere, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.OD_Sphere, "", new { @class = "text-danger" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.OD_Cylinder, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.OD_Cylinder, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.OD_Cylinder, "", new { @class = "text-danger" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     @Html.LabelFor(model => model.Axis, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.Axis, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.Axis, "", new { @class = "text-danger" }) 
     </div> 
    </div> 

    <div class="form-group"> 
     <div class="col-md-offset-2 col-md-10"> 
      <input type="submit" value="Create" class="btn btn-default" /> 
     </div> 
    </div> 
</div> 
    } 

    <div> 
    @Html.ActionLink("Back to List", "Index") 
    </div> 

    @section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
     } 

Ceci est mon contrôleur:

public class OpticalcTestController : Controller 
{ 
    // GET: OpticalcTest 
    public ActionResult Index() 
    { 

     return View(); 
    } 
}   

Comment puis-je obtenir les valeurs sur les cases "editfor", effectuer des calculs sur eux, puis passez les résultats de ces calculs (plusieurs résultats, pas un seul) à certaines étiquettes de la vue?

C'est une chose tellement simple dans Winforms, qui est ce que je travaille habituellement avec, mais je suis à mon esprit en essayant de trouver une réponse à cela. Il semble que les 9 000 autres résultats que je reçois des recherches concernent toujours l'écriture des données (en tant que modèle entier) dans une base de données. Cela n'aura pas de base de données. C'est juste une forme qui prend des valeurs numériques, fait des calculs et recrache des résultats. Pour plus de précision, comment extraire ces valeurs dans le contrôleur, Ajouter une sphère à un cylindre, puis ajouter un cylindre à l'axe et renvoyer les deux résultats séparément aux étiquettes (ou d'une autre manière pour les voir)?

Merci, R

+0

Notez qu'il est parfaitement possible d'effectuer des calculs mathématiques en JavaScript, vous n'avez donc pas besoin de renvoyer les valeurs au serveur pour effectuer des calculs. Sauf si vous avez des raisons spécifiques (telles que cacher vos calculs aux concurrents) pour les mettre sur le serveur. – NightOwl888

+0

J'ai pensé à faire cela, mais il va y avoir beaucoup de calculs et j'ai besoin d'un bon débogage et de la possibilité d'écrire des cas de test. – rmnrdi

+0

Si vous avez besoin de faire cela sur le serveur, vous devriez utiliser ajax pour publier les valeurs et mettre à jour le DOM avec la valeur retournée pour améliorer les performances –

Répondre

0

Vous aurez besoin d'une méthode HttpPost pour accepter le modèle à partir de la vue et accéder aux propriétés liées aux éléments auxiliaires EditorFor comme écrit maccettura.

Ensuite, vous pouvez effectuer des calculs comme si dans la méthode:

double sphereRadius = model.OD_Sphere/2; // demo calc 

-ce que les résultats de calcul vont être sur le même point de vue? Même modèle? En supposant que oui, je recommanderais de nouvelles propriétés de modèle pour les valeurs calculées, puis les lier à votre vue. Vous pouvez utiliser Razor pour afficher/masquer les entrées et les valeurs calculées selon les besoins.

Exemple en supposant que vous utilisez le calcul ci-dessus w/une nouvelle propriété de modèle:

public class OpticalcTestViewModel 
{ 
    public double OD_Sphere { get; set; } 
    public double OD_Cylinder { get; set; } 
    public int Axis { get; set; } 

    public double sphereRadius { get; set; } // new calculated property 
} 

[HttpPost] 
public ActionResult Index(OpticalcTestViewModel model) 
{ 
    double sphereRadius = model.OD_Sphere/2; // demo calc 
    model.sphereRadius = sphereRadius; 
    return View(model); 
} 

Notez que si vous essayez de modifier une propriété modèle qui a déjà été lié à la vue, il conservera sa valeur ancienne . En effet, la valeur est réellement conservée dans ModelState et le classeur de modèle par défaut y vérifie d'abord et utilise des valeurs si elles existent. Pour surcharger cela, vous devrez effacer la propriété ModelState, mais cela devient un peu compliqué.

+0

Explication fantastique! C'est ce que j'avais besoin de savoir. Une dernière chose. J'ai quelques calculs à effectuer. Le contrôleur est-il le meilleur endroit pour cela? Le ViewModel serait-il un meilleur endroit pour cela? Ou devrais-je passer le modèle dans une classe séparée qui effectue tous les calculs et retourne ensuite le modèle? – rmnrdi

+1

Strictement une question de préférence. Le mien est de garder les contrôleurs légers, donc je crée des méthodes Factory statiques pour faire des choses comme les calculs et les appels de base de données. – akerra

+1

Il n'y a rien de tel que 'ViewState' dans mvc. Ce à quoi vous faites référence est ModelState –

1

La première chose que vous devez faire est d'ajouter une action à votre contrôleur qui accepte un paramètre de type OpticalcTestViewModel et est marqué avec l'attribut [HttpPost]:

[HttpPost] 
public ActionResult Index(OpticalcTestViewModel model) 
{ 
    //perform calculations 
    return View(model); 
} 

Comme vous remarquez ci-dessus, après avoir effectué les calculs, vous devrez modifier la variable model pour l'ajouter dans vos nouveaux calculs, puis renvoyez-la à la vue (return View(model)).

Votre formulaire dans la vue effectue un POST par défaut. Comme vous n'avez aucune action capable de gérer une requête POST, vous ne serez jamais capable de gérer ces appels. Le code ci-dessus devrait corriger tout cela.

Dans les deux cas, je voudrais hautement recommandons de prendre quelques tutoriels sur ASP.NET MVC. Microsoft a quelques tutoriels décents, mais il y a aussi beaucoup de ressources gratuites en ligne.

+0

Merci maccettura. J'ai essayé de travailler sur des tutoriels dans le passé, mais ça semble toujours se terminer de la même manière. Moi, ennuyé de mon esprit, le code cassé et plus de questions que de réponses. Je continue de les faire, mais je n'en ai pas trouvé beaucoup dont je reçois beaucoup. Malheureusement, l'apprentissage par tutoriel est vraiment sous-optimal, car il ne permet pas de questions. Alors que nous sommes sur le sujet des tutoriels. Aucune suggestion? Des tutoriels qui vous ont vraiment donné le moment "ah ah"? – rmnrdi