Twitter status HtmlHelper del 2

I det tidigare inlägget skrev jag om hur man kunde skapa en HtmlHelper för att kunna visa senaste Twitter statusen för en användaren. I denna del tänkte jag ta upp hur man kan hantera flera användare och styra layouten lite lättare.

Vi utgår från tidigare inlägg, där vi har “TwitterStatus”, “FetchTwitterStatus” funktionerna. Vi börjar med att prata om hur vi kan hantera flera användare, till exempel att den skriver ut den första Twitter statusen från två olika användare.

I mappen “Models” så skapar vi en klass som heter “Users.cs”, i den skapar vi två klasser, “Users” och “Twitter”. Där “Twitter” ärver av “IEnumerable” som finns i namespacet “System.Collections”. “Users” klassen är väldigt simpel, ser ut såhär.

public class Users
{
public string TwitterAccount { get; set; }
}

Det är allt vi behöver “Users” klassen till. I klassen “Twitter” så skapar vi en privat ArrayList med namnet “twitterAccounts”.

public class Twitter : IEnumerable
{
private ArrayList twitterAccounts;

public Twitter()
{
twitterAccounts = new ArrayList();

twitterAccounts.Add(new Users { TwitterAccount = "Frozzare" });
twitterAccounts.Add(new Users { TwitterAccount = "Vimpyboy" });
}

public IEnumerator GetEnumerator()
{
return (twitterAccounts as IEnumerable).GetEnumerator();
}

}

Våran publika “Twitter” använder vi för att lägga till våra Twitter konton in i ArrayList “twitterAccounts” som vi skapade. “IEnumerator GetEnumerator()” samlar ihop all data, i detta fall twitterAccounts till en collection och returnerar allt som IEnumerable som används för att skriva ut saker till en View i ASP.NET MVC.

För att skriva ut våra användare med Html.TwitterStatus(int, string, bool), så går vi till en Controller klass, jag väljer “HomeController.cs”. Då lägger vi till “using DittProjekt.Models”, då får vi tillgång till våran Twitter klass.

public ActionResult Page()
{
return View(new Twitter());
}

Nu så behöver vi bara skriva “new Twitter()” inom “View” sedan högerklickar vi på våran kod och väljer “Add View”, då får vi upp denna ruta.

add-view-page

Där vi väljer vi våran “Twitter” klass som “View data class” sen så skapar vi sidan. Nu behöver vi importera två namespaces, “DittProjekt.Helpers” för att få fram våran TwitterStatus HtmlHelper från tidigare och “DittProjekt.Models” för att få fram “Users” klassen.

<% foreach (Users u in Model)
{%>
<%= Html.TwitterStatus(1, u.TwitterAccount, false) %>
<% } %>

Nu så skriver vi bara “foreache (Users u in Model)” som betyder för varje “u” användare i “Model” som är våran Twitter klass. Sedan är det bara att skriva “u.TwitterAccounts” som användarnamn i våran TwitterStatus HtmlHelper.

Nu ser vi att det kommer Twitter statusar från två olika användare. Nu tänkte jag prata vidare om hur vi kan hantera layouten lättare. Vi skapar en ny funktion, “TwitterStatusLink” som ser ut såhär

public static string TwitterStatusLink(this HtmlHelper helper, int numberOfMessages, string username, bool splitUserNameAndLink)
{
return TwitterHtml(FetchTwitterStatus(username, numberOfMessages).AsQueryable<Twitter>(), splitUserNameAndLink);
}

Det inte så konstigt ut? Vi kommer skapa funktionen “TwitterHtml” straxs. I klassen “Twitter” har jag lagt till en sträng för “Username”.

public string UserName { get; set; }

I funktionen “FetchTwitterStatus” har jag ändrat om lite i våran “foreache” loop som ser ut såhär nu

   foreach (XElement elm in children)
{
Twitter tw = new Twitter();
tw.Status = elm.Element("description").Value;
tw.DateDiff = DateTime.Parse(elm.Element("pubDate").Value).ToLongDateString();
tw.Link = elm.Element("link").Value;
string splitStatus = tw.Status.Remove(0, user.Length + 1);
        tw.UserName = tw.Status.Remove(user.Length + 1, splitStatus.Length);
        tw.Status = splitStatus; 
messages.Add(tw);
}

Det jag ändrat i “foreache” loopen är att vi delar på strängen och får ut användarnamnet den vägen så vi kan lägga till det i våran “IList<Twitter>”. Sedan ärver “tw.Status” den strängen vi delat på så vi får bort användarnament från statusen.  Notera att jag sätter “tw.Status” under “tw.UserName”.

public static string TwitterHtml(IQueryable<Twitter> source, bool splitUserNameAndLink)
{
foreach (var item in source)
{
if (splitUserNameAndLink)
return String.Format("{0} <a href=\"{1}\">{2}</a> - {3}", item.UserName, item.Link, item.Status, item.DateDiff);
else
return String.Format("<a href=\"{0}\">{1}</a> - {2}", item.Link, item.UserName + item.Status, item.DateDiff); ;
}

return string.Empty;
}

Inga konstigheter? Vi skickar in våran source, som är “FetchTwitterStatus”. Man behöver inte göra om den till “IQueryable” fungerar utmärkt att skriva “IList<Twitter> source” men jag tycker det är trevligare. Ni minns kanske “foreache” loopen från “TwitterStatus” funktionen, det är nästan samma. Skillnaden är att vi tagit bort “StringBuilder” då vi bara ska returnera en sträng. Vi har tagit bort “<ul>” listan då vi kommer lösa det på annat sätt. Vi behöver ha “return” som returnerar en tom sträng om inget i “foreach” loopen inte skulle returnera något.

Det kommer bli en liten skillnad på hur vi skriver ut detta nu.

<% foreach (Users u in Model)
{ %>
<%= Html.TwitterStatusLink(1, u.TwitterAccount, true) %>
<% } %>

twitter-5

Som ni ser på bilden så får vi ingen list formatering. Skulle vi vilja ha en “<ul>” lista så skriver vi det såhär

<ul>    
<% foreach (Users u in Model)
{ %>
<li><%= Html.TwitterStatusLink(1, u.TwitterAccount, true) %></li>
<% } %>
</ul>

twitter-4

På det här sättet kan vi styra layouten bättre.

No Comments