2017-01-12 6 views
0

MVCの世界はまったく新しいので、ここで何か正しいことをしていないと確信しています。モデルのページからビューインデックスページの関数を呼び出して、いくつかのツールチップを設定しようとしています。私のモデルではモデルに入れるためのプロパティを呼び出す

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(); } } 
} 

そして、私の意見で:

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

    ViewBag.pageTips = blah; 

    return getMainData(); 
} 

そして私はかみそりのページでこれを持っている:

例2が表示されるはずです
@Html.Raw(ViewBag.pageTips[1]) 

ページのではなく、と表示されますnullをツールチップの値として使用します。

現在のところ、私のビューでpageTipsの返品に来ると、値はnullになります。

どうして私は間違っていますか?私はいくつかのストップをここに入れて、allTips()関数を呼び出すことは決してありませんので、それを行うためには何が必要なのかについての良い出発点です。

私はちょうど.getTipsを呼び出すとtheTips機能をオフに解雇することを考え出しましたか?

+0

getMainDataメソッドがViewbagをクリーンアップする何かをしないことは確かですか? –

+0

@ RobertoCarlosええと、ViewBagsなどのデータを追加しますが、pageTips ViewBagには何も配置しません。 – StealthRT

+1

あなたのモデルは* very * strangeです。しかし、最終的には、あなたは '_tips'をインスタンス化することはありません。だからこそ、それは 'ヌル'だ。 – David

答えて

3

あなたはsetterの概念を誤解していて、それを「初期設定子」として使用していますが、設定者は値を設定して他の単語に変更することを意図しています。それを初期化したい場合はコンストラクタで行います。

ここでは2つの異なるリストを使用していますが、なぜ私は本当にその理由はわかりません。 作業コードは次のようになります。

コントローラで次に
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; } } 
} 

ViewBag.pageTips = new tips().getTips; 

次にビューでこのようにそれを呼び出す:

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

これは最高の答えです。セッターに渡された価値を完全に無視するという誤解を明らかに説明することは、**把握するための**非常に重要な概念です。そのクラスを使っている人は誰でも、プロパティに割り当てられた値がどこにも見つからないということはまったく思いがけないでしょう。 – krillgar

+0

@killgar実際にプロパティのセッターで 'value'を使用していないのは明らかにアンチパターンです – Piou

+0

助けてくれてありがとう、@Piou!確かにこれは正しい答えです。それは上記の私自身の例を反映していますが、私が持っていた問題を解決します。 – StealthRT

4

あなたはコンストラクタを混乱しているように見えますお使いのモデルではのプロパティとなりますが、これは非常に奇妙です。私はあなたの代わりにこのような何かをしたい疑う:

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"); 
    } 
} 

あなたTipsプロパティが自動的にちょうどすぐに移入されますので、ここでの考え方は、あなたがオブジェクトの新しいインスタンスを作成するとき、コンストラクタは、デフォルトでと呼ばれているということですこれのインスタンスを作成します。 TipsObjのインスタンスを作成し、そのインスタンスのTipsプロパティにViewBagプロパティを設定します

var tips = new TipsObj(); 

ViewBag.pageTips = tips.Tips; 

は、その後、あなたのコントローラのアクションには、単にこれを行うことができます。そのオブジェクトのコンストラクタで初期化されたものです。

これは本当にMVCとは関係がないことに注意してください。これはC#でオブジェクトを作成し、そのオブジェクトのプロパティを使用することです。

ここでもいくつかの名前を変更しました。 C#では、クラス名は大文字で始まる必要があります。また、のすべてを「ヒント」と呼ぶことは望ましくありません。には「blah」と電話したくありません。意味のある、直感的な名前を使用すると、コードを理解しやすくなり、作成する内容を理解するのに役立ちます。

+0

すべての知識ありがとう、David。 :o) – StealthRT

1
次のようにモデルを変更し

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; 
    } 
} 

そして、それを使用する:

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

**メソッドはpublicヒント()関数で戻り値の型**エラーを持たなければなりません。 – StealthRT

+2

@StealthRT:この回答のコードは、そのエラーを生成しません。 (C#は大文字と小文字を区別します) – David

+0

@StealthRTこれはコンストラクタです。クラス名と同じ名前にする必要があります – meda

1

あり間違ってここにいくつかの事がありますが、私は直接あなたの質問に答える始めましょう... ViewBag.pageTips [1]がnullである理由は、モデル内の_tips配列を決して初期化しないためです。それを行う唯一のコードは、getTipsプロパティのsetterであり、呼び出されることはありません。デバッガをアタッチすると明らかになります:)

allTips()メソッドをコンストラクタに変更してコレクションを初期化するなど、いくつかの方法でこれをリファクタリングすることができます。

私はそれを直接的に例にしたくありません。あなたはMVCの初心者だとおっしゃったので、これをどうやって行うのかをお見せしたいと思います。 MVCの最大のメリットの1つはモデルバインディングなので、ViewBagは忘れてしまいます。 代わりにこれを試してみてください:

モデル

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"}; 
     } 
    } 
} 

コントローラ

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

     return View(model); 
    } 

ビュー

@model WebApplication1.Models.TipsModel 

@{ 
    ViewBag.Title = "Index"; 
} 

@Model.Tips[1] 
+0

説明をありがとう!しかし、私の例では分かるように、View戻り値** getMainData()**をすでに持っていますので、** getMainData()**と** View(model)**のどちらを返すのですか? – StealthRT

+0

私はgetMainData()をまったく持っていないでしょう。あなたのコードで呼び出された場所は理にかなっていないようです。名前はあなたが「データを取得している」と推測しますが、アクションのreturn文の一部として呼び出されているので、getMainData()メソッドは、何らかの種類のActionResult(データではありません)の戻り型を持たなければなりません。モデルがあなたのためにデータを取得し、それをビューに渡します。それは理にかなっていますか? – Steve

+0

正直なところ私はそれを信じていません。単にMVCを理解しようとすると、私にとって大きな問題になります。私は過去のASP.netフォームから来ています。だから私はちょうど私が参照しなければならない別の場所にそれを持たずに、コード内の任意のページのデータを取得することに慣れています。ちょうど別の場所にコードを持っているだけの価値よりも多くの仕事のように思えます。 – StealthRT

関連する問題