2017-01-12 1 views
0
zu füllen

Hey alle neuen MVC Welt, so bin ich mir sicher, dass ich hier etwas nicht richtig machen. Ich versuche, eine Funktion von der Modellseite aus meiner Ansichtsindexseite aufzurufen, um einige QuickInfos zu füllen.Call-Eigenschaft in Modell

In meinem Modell:

public class tips 
{ 
    public List<string> allTips() 
    { 
     List<string> theTips = new List<string>(); 

     theTips.Add("example 1"); 
     theTips.Add("example 2"); 

     return theTips; 
    } 

    private List<string> _tips; 
    public List<string> getTips { get { return _tips; } set { _tips = allTips(); } } 
} 

Und meiner Meinung nach:

public ActionResult Index() 
{ 
    var blah = new tips().getTips; 

    ViewBag.pageTips = blah; 

    return getMainData(); 
} 

Und dann habe ich diese auf der Rasierklinge Seite:

@Html.Raw(ViewBag.pageTips[1]) 

Welche Beispiel anzeigen soll 2 auf der Seite, aber es zeigt nur Null als Wert für die QuickInfos.

Momentan hat es einen Wert von null wenn es um die Rückgabe für die pageTips in meiner Ansicht geht.

Also was würde ich falsch machen? Ich habe hier und da einige Stopps gesetzt und bemerke, dass es nie die allTips() Funktion aufruft, so dass das ein guter Startpunkt dafür ist, was ich tun muss, um das zu tun.

Ich dachte nur, dass der Aufruf den .getTips würde die theTips Funktion abfeuern?

+0

Sind Sie sicher, dass die getMainData-Methode nicht etwas tut, das den Viewbag säubert? –

+0

@RobertoCarlos ja, es legt nur einige weitere Daten in ViewBags und so, aber nichts in den PageTips ViewBag. – StealthRT

+1

Ihr Modell ist * sehr * seltsam. Aber letztendlich implizierst du '_tips' niemals. Deshalb ist es "null". – David

Antwort

3

Sie missverstehen das Konzept von setter und verwenden es als "Initialisierer", ein Setter soll den Wert festlegen, um es in anderen Worten zu ändern. Wenn Sie es initialisieren wollen, tun Sie es im Konstruktor.

Hier verwenden Sie zwei verschiedene Listen, ich weiß nicht wirklich warum. Ein Arbeits Code wäre:

public class tips 
{ 
    public tips() 
    { 
     _tips = new List<string>(); 

     _tips.Add("example 1"); 
     _tips.Add("example 2"); 
    } 

    private List<string> _tips; 
    public List<string> getTips { get { return _tips; } set { _tips = value; } } 
} 

Dann in der Steuerung:

ViewBag.pageTips = new tips().getTips; 

es dann in der Ansicht auf diese Weise nennen:

@Html.Raw(ViewBag.pageTips[1]) 
+1

Dies ist die beste Antwort. Das Missverständnis, den Wert, der an den Setter weitergegeben wird, völlig zu ignorieren, ist eindeutig ein sehr wichtiger Begriff, den es zu verstehen gilt. Jeder andere, der diese Klasse benutzt, wäre völlig verblüfft, dass die Werte, die sie einer Eigenschaft zugewiesen haben, nirgendwo zu finden sind. – krillgar

+0

@krillgar in der Tat nicht mit "Wert" in der Setter der Eigenschaft ist eindeutig ein Anti-Muster – Piou

+0

Danke für die Hilfe, @Piou! In der Tat ist dies die richtige Antwort, da sie mein eigenes Beispiel oben widerspiegelt - aber das Problem löst, das ich hatte. – StealthRT

4

Sie scheinen Bauer zu sein verwirrend mit Eigenschaften in Ihrem Modell, das ist sehr seltsam. Ich vermute, dass Sie so etwas wie dies wollen statt:

public class TipsObj 
{ 
    // a property 
    public List<string> Tips { get; set; } 

    // a constructor 
    public TipsObj() 
    { 
     Tips = new List<string>(); 

     Tips.Add("example 1"); 
     Tips.Add("example 2"); 
    } 
} 

Die Idee dabei ist, dass der Konstruktor standardmäßig aufgerufen wird, wenn Sie eine neue Instanz des Objekts erstellen, so dass Ihre Tips Eigenschaft wird sofort automatisch ausgefüllt werden, nur indem Sie eine Instanz von diesem erstellen.

Dann in Ihrem Controller-Aktion können Sie dies einfach tun:

var tips = new TipsObj(); 

ViewBag.pageTips = tips.Tips; 

, die eine ViewBag Eigenschaft auf die Tips Eigenschaft dieser Instanz eine Instanz des TipsObj und eingestellt werden erstellen.Das wurde im Konstruktor dieses Objekts initialisiert.

Beachten Sie, dass nichts davon wirklich etwas mit MVC zu tun hat, dies ist nur ein Objekt in C# erstellen und eine Eigenschaft für dieses Objekt verwenden.

Beachten Sie auch, dass ich hier einige der Namen geändert habe. In C# -Klassen sollten die Namen mit einem Großbuchstaben beginnen. Auch wollen Sie nicht anrufen alles "Tipps" (und Sie wollen nicht anrufen irgendetwas "blah"). Durch die Verwendung aussagekräftiger und intuitiver Namen wird Ihr Code leichter verständlich. So können Sie besser verstehen, was Sie schreiben.

+0

Vielen Dank für das Wissen, David. : o) – StealthRT

1

Ihr Modell ändern wie folgt aus:

ViewBag.pageTips = new Tips().getTips(); 
+0

** Methode muss einen Rückgabetyp ** Fehler bei der öffentlichen Tips() -Funktion haben. – StealthRT

+2

@StealthRT: Der Code in dieser Antwort erzeugt diesen Fehler nicht. (Beachten Sie auch, dass C# Groß-und Kleinschreibung ist.) – David

+0

@StealthRT es ist ein Konstruktor, sollte der gleiche Name wie Ihre Klasse sein – meda

1

Es gibt ein paar Dinge falsch hier, aber ich werde direkt mit der Beantwortung Ihrer Frage beginnen ...:

public class Tips 
{ 
    private List<string> _tips {get; set;} 

    public Tips() 
    { 
     _tips = new List<string>(); 
     _tips.Add("example 1"); 
     _tips.Add("example 2"); 
    } 

    public List<string> getTips() 
    { 
     return _tips; 
    } 
} 

dann verwenden, Der Grund dafür, dass ViewBag.pageTips [1] null ist, liegt darin, dass Sie das _tips-Array in Ihrem Modell niemals initialisieren. Der einzige Code, der das tun würde, befindet sich im Setter der getTips-Eigenschaft, der nie aufgerufen wird. Wenn Sie einen Debugger anfügen, wird es offensichtlich sein :)

Sie könnten dies auf mehrere Arten umgestalten, einschließlich der Änderung der allTips() -Methode zu einem Konstruktor und Initialisieren Ihrer Sammlung dort.

Ich möchte nicht ein Beispiel dafür direkt aber setzen. Du hast erwähnt, dass du neu bei MVC bist, also möchte ich dir zeigen, wie das wirklich gemacht werden sollte. Einer der großen Vorteile von MVC ist Model Binding, also vergiss ViewBag. dieses Versuchen Sie stattdessen:

Das Modell

using System.Collections.Generic; 

namespace WebApplication1.Models 
{ 
    public class TipsModel 
    { 
     public List<string> Tips { get; } 

     public TipsModel() 
     { 
      Tips = new List<string> {"example 1", "example 2"}; 
     } 
    } 
} 

Der Regler

public ActionResult Index() 
    { 
     var model = new TipsModel(); 

     return View(model); 
    } 

The View

@model WebApplication1.Models.TipsModel 

@{ 
    ViewBag.Title = "Index"; 
} 

@Model.Tips[1] 
+0

Danke für die Erklärung! Wie Sie wahrscheinlich in meinem Beispiel sehen, habe ich bereits eine View-Rückgabe ** return getMainData() **, also wie würde ich sowohl ** getMainData() ** als auch ** View (Modell) ** zurückgeben? – StealthRT

+0

Ich hätte getMainData() überhaupt nicht. Wo es in Ihrem Code aufgerufen wird, scheint keinen Sinn zu ergeben. Der Name besagt, dass Sie "Daten erhalten", aber da sie als Teil der return-Anweisung einer Aktion aufgerufen wird, muss die getMainData() -Methode den Rückgabetyp einer Art von ActionResult haben (was keine Daten ist). Lassen Sie das Modell die Daten für Sie abrufen und übergeben Sie sie an die Ansicht. Ist das sinnvoll? – Steve

+0

Ehrlich @Steve es nicht. Einfach versuchen, die MVC zu verstehen, ist ein großes Problem für mich. Ich bin von der ASP.net Formulare Vergangenheit und so bin ich nur daran gewöhnt, die Daten für eine bestimmte Seite im Code zu bekommen, ohne sie an einem anderen Ort zu haben, auf den ich verweisen muss und alles. Scheint einfach mehr Arbeit als es wert ist, nur Code an einem anderen Ort zu haben. – StealthRT