2017-05-08 8 views
1

は、脳のおならを持って...このモデル与えられた:カミソリビューは、フロー

public class Result 
{ 
    public decimal Cost {get;set;} 
} 

そして、この極端に簡略化ビュー:

@{ 
    decimal resultsTotal = 0; 
} 

<div>@resultsTotal</div> //need the total from the loop below here 

@foreach(var result in Model.Results) 
{ 
    resultsTotal += result.Cost; 

    <div>@result.Cost</div> 
} 

私はresultsTotal変数 foreachループの上に表示する必要があります。私は@Model.Results.Sum(x => x.Cost)のビューで、モデルまたはコントローラ、ポイントが私はResultsを複数回列挙することを避けるためにほしいと思うことを望んでいることを実現します。恐らく結果をバッファリングして、おそらくまたはをループした後にdivを更新する予定はありますか?はい、私もjqueryを使うことができましたが、それはにおいがします。

答えて

1

あなたはhelperを使用して、バッファに結果を書き込むことができます:

@{ 
    IEnumerable<Result> results = Model.Results; 
    decimal resultsTotal = 0; 
    var buffer = new List<HelperResult>(); 
} 

@foreach(var result in Model) 
{ 
    resultsTotal += result.Cost; 
    buffer.Add(ResultRow(result)) 
} 

<div>@resultsTotal</div> 

@foreach (var result in buffer) 
{ 
    @result 
} 

@helper ResultRow(Result result) 
{ 
    <div>@result.Cost</div> 
} 
+0

'HelperResult'を使う代わりに、 StringBuilder'それから 'Html.Raw'それです。結果を1回だけ列挙します。 – mxmissile

+0

そう簡単に何かのためにやっているのは本当に正しいことではありません。モデルをビュー内で計算する必要なしにビューに表示できる状態にするためには、必要な処理を行うことを強くお勧めします。データが複数回ループしてはならない理由はありますか?幸運の私の友人:) – Luke

+0

@ルーキーのyea私は(パフォーマンス)の要件は理想的ではないが、それはそれが何であるか知っている。私は実際に私のコマンドにすべてを移動し、生成されたHTMLテーブルを 'StringBuilder'に私のモデルの一部として保存して、私のビューに出力しました。 – mxmissile

1
@{ 
    IEnumerable<Result> results = Model.Results; 

    @foreach(var result in Model=) 
    { 
     <div>@result.Cost</div> 
    } 

    var resultsTotal = Model.Results.Sum(x => x.Cost) 
} 

<div>@resultsTotal</div> 

@{}は、コードの実行に使用できるコードブロックです。私はこのようにすることをお勧めしません。ビューにロジックを置くことはちょうど正しい汚れです。

コントローラのアクションメソッド内でこの計算を行い、モデルを介してビューに渡す必要があります。

本の線に沿って何か...

public ActionResult Index() 
{ 
    // ... get your results from wherever you got them from before, eg your service ... 
    IEnumerable<Result> results = myService.GetResults(); 

    decimal resultsTotal = 0; 

    var responseModel = new YourViewModel 
    { 
     Results = results, 
     ResultsTotal = results.Sum(x => x.Cost) 
    }; 

    return View(responseModel); 
} 

そして、あなたは、ロジックの最小限の量で、ビューのあなたのコントローラ内ですでに計算されている情報を表示することができます。

@foreach(var result in Model.Results) 
{ 
    <div>@result.Cost</div> 
} 

<div>@Model.ResultsTotal</div> 
+0

申し訳ありませんが、私は明確ではなかった、 'resultsTotal' divはforeeachループの上に表示する必要があります。 – mxmissile

+0

私は、Sumメソッドでは1回、ビューでは1回だけループを2回繰り返すことができました。 – mxmissile

+0

あなたのforループを文字列に出力する(いくつかのやり方は?)最初にそれを出力した後、 'resultsTotal'値の出力後にページに出力するような、本当に悪いことをしないと本当に別の方法はありません... – Luke

1

ロジックをビューからビューモデルに移動します。残念ながら、どのタイプの計算をしたいのかははっきりさせていませんが、一般的に、それらの計算の結果を返すビューモデルにプロパティを追加するだけで、必要に応じてチェーン化することができます。例:

public class MyAwesomeViewModel 
{ 
    public List<Result> Results { get; set; } 

    public decimal Total 
    { 
     get { return Results.Sum(x => x.TotalCost); 
    } 

    public decimal AverageCost 
    { 
     get { return Total/Results.Count(); } 
    } 
} 

public class ResultViewModel 
{ 
    public decimal TotalCost 
    { 
     get { return Cost + Tax + Shipping; } 
    } 
} 

多くの場合、私はちょっと例を挙げて説明します。あなたの計算を慎重な単位に分解し、それらをバックアップしてください。これにより、計算が簡単になるだけでなく、必要に応じてコンポーネントの計算にアクセスすることができます。そうすれば、あなたの意見を比較的論理的に自由に保つことができます。

+0

申し訳ありませんが、私の質問は間違っていたと思います。私は計算が心配ではなく、どこで起こったのか、私は結果を何度も繰り返すことに心配しています。 LINQ SumとCountメソッドは結果をループします(舞台裏で)。 – mxmissile

+0

LINQはかなり速いですが、関係なく、あなたが望むことをする方法はありません。 forループの前に合計を表示する必要がある場合は、2回反復する必要があります。 –

関連する問題