A dynamic menu - fully populated from data stored in MS SQL - fed via a web service.
It is important to mention that most of the functionality was pretty much handled in the web service (IMO, that is how it should be).
The only thing I learnt in flex through this project was to use the Menu control and to perform a simple WS call.
The database has a table 'tbl_menu' that stores all the menu details. It references itself via the field ParentMenu_id for sub menus.
The only input the Flex page needs is a cleanly formatted xml string. So that is what the WS is going to return:
[WebMethod]
public string GetMenuByClass(String usrclass)
{
StringBuilder sb = new StringBuilder();
Dictionary> dict = new Dictionary >();
dict = GetMenuDict(usrclass);
sb.Append("");
sb.Append("");
return sb.ToString();
}
It is just a plain method that uses StringBuilder to append the xml string. There are a hundred different ways to construct the xml, but that is not part of this sample.
Also you would notice soon that we are using a simple object class 'MenuInfo' that represents the actual DB entity which will be used that to pass around data.
Next, the GetMenuDict function takes care of populating a dictionary with all the menu data it pulled from the DB:
private Dictionary> GetMenuDict(string userAccessCode)
{
Dictionary> dict = new Dictionary >();
ListmenuItems = new List ();
menuItems = GetMenuFromDB(userAccessCode);
foreach (MenuInfo m in menuItems)
{
// root element - 0 or NULL
if (m.Parent_Link_id == 0)
{
if (dict.ContainsKey(m.Parent_Link_id))
{
dict[m.Parent_Link_id].Add(m);
}
else
{
Listlst = new List ();
lst.Add(m);
dict.Add(m.Parent_Link_id, lst);
}
}
else
{
// not a root element - parent exists. find it and add this guy to his list
MenuInfo mInfo = null;
foreach (int key in dict.Keys)
{
mInfo = FindMenuInfoRecursive(m.Parent_Link_id, dict[key]);
if (mInfo != null)
{
mInfo.menuList.Add(m);
}
}
}
}
return dict;
}
The GetmenuFromDB just reads the data from the Database using a datareader and returns a list of MenuInfo. The more inportant function is the FindMenuInfoRecursive, which takes care of handling the sub menus. With this method the sample supports infinite level of sub listing menu items, by just setting the appropriate ParentMenu_id.
private MenuInfo FindMenuInfoRecursive(int id, ListmenuList)
{
MenuInfo menu = null;
foreach (MenuInfo item in menuList)
{
if (item.Menu_id == id)
{
menu = item;
break;
}
else
{
menu = FindMenuInfoRecursive(id, item.menuList);
if (menu != null)
{
break;
}
else
{
continue;
}
}
}
//finally return the menu object
return menu;
}
The AddXmlString is the method we are going to see next:
private string AddXmlString(ListmenuList)
{
StringBuilder sb = new StringBuilder();
foreach (MenuInfo m in menuList)
{
if (m.menuList.Count > 0)
{
//should continue
sb.Append(String.Format("- ", m.Name, m.Name));
", m.Name, m.Name));
sb.Append(AddXmlString(m.menuList));
sb.Append(String.Format("
}
else
{
sb.Append(String.Format("- ", m.Name, m.Name));
}
}
return sb.ToString();
}
With all this done at the WS, it leaves us with very little to do at the Flex end. We would just be making the call to the WS and merely bind the results.
public function WSMenuSvcResultHandler(event:ResultEvent):void{
var dataXML:XML = new XML();
dataXML = XML(event.result.toString());
var myMenu:Menu = Menu.createMenu(null, dataXML, false);
myMenu.labelField="@label";
myMenu.show(10, 20);
}
The full C# source for this example is here and the Flex source is here.
No comments:
Post a Comment