/ / मैं रेजर के लिए एक "साइकिल" सहायक कैसे बना सकता हूं? - c #, asp.net-mvc-3, रेजर, साइकिल, हेल्पर्स

मैं रेजर के लिए एक "साइकिल" सहायक कैसे बना सकता हूं? - c #, asp.net-mvc-3, रेजर, साइकिल, हेल्पर्स

मूल रूप से, मैं जोड़ना चाहता हूं यह सहायक रेजर को। मैंने क्या कोशिश की:

public static class Html
{
static Dictionary<string[], int> _cycles;

static Html()
{
_cycles = new Dictionary<string[], int>();
}

public static string Cycle(this HtmlHelper helper, string[] options)
{
if (!_cycles.ContainsKey(options)) _cycles.Add(options, 0);
int index = _cycles[options];
_cycles[options] = (options.Length + 1) % options.Length;
return options[index];
}

उपयोग:

<tr class="@Html.Cycle(new[]{"even","odd"})">

लेकिन यह सिर्फ हर पंक्ति के लिए "भी" कहता है ... यकीन नहीं है कि क्यों। मुझे यकीन नहीं है कि जब यह वर्ग त्वरित हो जाता है ..... तो क्या यह अनुरोध के अनुसार एक बार है, एक बार प्रति सर्वर चलता है ... या क्या? भले ही ... मैं इसे कैसे ठीक करूंगा ताकि यह इच्छित विकल्प प्रदान करे?


प्रयास # 2

public static class Html
{
public static string Cycle(this HtmlHelper helper, params string[] options)
{
if(!helper.ViewContext.HttpContext.Items.Contains("cycles"))
helper.ViewContext.HttpContext.Items["cycles"] = new Dictionary<string[],int>(new ArrayComparer<string>());
var dict = (Dictionary<string[], int>)helper.ViewContext.HttpContext.Items["cycles"];
if (!dict.ContainsKey(options)) dict.Add(options, 0);
int index = dict[options];
dict[options] = (index + 1) % options.Length;
return options[index];
}
}

class ArrayComparer<T> : IEqualityComparer<T[]>
{
public bool Equals(T[] x, T[] y)
{
if (ReferenceEquals(x, y)) return true;
if (x == null || y == null) return false;
if (x.Length != y.Length) return false;
for (int i = 0; i < x.Length; ++i)
if (!x[i].Equals(y[i])) return false;
return true;
}

public int GetHashCode(T[] obj)
{
return obj.Length > 0 ? obj[0].GetHashCode() : 0;
}
}

इसके साथ कोई समस्या?

उत्तर:

जवाब के लिए 2 № 1

यह कारण विफल हो रहा है, क्योंकि आप हर बार शब्दकोश की कुंजी के रूप में एक नए सरणी का उपयोग कर रहे हैं।

मैं सिर्फ एक अतिरिक्त पैरामीटर को शामिल करने की सलाह दूंगा जो कि एक तानाशाही कुंजी के रूप में उपयोग किया जाएगा।

तथा भगवान के लिए, कृपया एक निजी भंडारण क्षेत्र का उपयोग करें। (इसके बजाय static सदस्य, जो पेज पर कई थ्रेड हिट होने पर उड़ जाएगा।


उत्तर № 2 के लिए 1

आपके लिए हर कॉल Cycle विधि एक नया पास करती है options सरणी, शब्दकोश में एक नई कुंजी जोड़ना।


उत्तर № 3 के लिए 1

इसे और थ्रेडिंग समस्या दोनों को ठीक करने के लिए, आप स्ट्रिंग्स को स्वयं HttpContext में कुंजियों के रूप में उपयोग कर सकते हैं:

string key = "Cycle-"+String.Join("|", options);

if (!html.ViewContext.HttpContext.Items.Contains(key))
html.ViewContext.HttpContext.Items.Add(key, 0);
int index = html.ViewContext.HttpContext.Items[key];
html.ViewContext.HttpContext.Items[key] = (index + 1) % options.Length;
return options[index];

ध्यान दें कि यह बाल क्रियाओं और अनुभागों में चक्र साझा करेगा।


जवाब के लिए 0 № 4

पता चला कि मैं इसे an . के साथ कर सकता हूं @function साथ ही ... तो मुझे नामस्थान जोड़ने की आवश्यकता नहीं है Web.config.

@using MvcApplication4.Helpers @* for ArrayComparer *@

@functions {
public static string Cycle(params string[] options)
{
if (!HttpContext.Current.Items.Contains("Html.Cycle"))
HttpContext.Current.Items["Html.Cycle"] = new Dictionary<string[], int>(new ArrayComparer<string>());
var dict = (Dictionary<string[], int>)HttpContext.Current.Items["Html.Cycle"];
if (!dict.ContainsKey(options)) dict.Add(options, 0);
int index = dict[options];
dict[options] = (index + 1) % options.Length;
return options[index];
}
}

इसे an with के साथ भी कर सकते हैं @helper लेकिन मुझे नहीं लगता कि यह उतना साफ होगा।