José F. Romaniello

Las aventuras y desventuras de un codificador.

Sometimes I need to convert a domain object that represents a tree into another form of tree, whether to send it over the cable or simply for display it in a user control.

Here the code:

public static IEnumerable<TResult> TransformTree<TSource, TResult>(
         this IEnumerable<TSource> enumerable,
         Func<TSource, IEnumerable, TResult>  transformFunction,
         Func<TSource, IEnumerable<TSource>> getChildrenFunction)
{
 foreach (var item in enumerable)
 {
     yield return transformFunction.Invoke(item,
         getChildrenFunction.Invoke(item)
                            .TransformTree(transformFunction, getChildrenFunction)
         );
 }
}
This is an extension method for IEnumerable<TSource> (almost any collection type) that returns an IEnumerable<TResult>. The second parameter is the “transform function”, in this place you must specify how transform TSource in TResult. The third parameter is the “get children function”, here you must specify how to retrieve the children from TSource. I use this function to build a graph object to put into extjs tree panel as json. Take a look at the code:
var query = daoPersons.ToList().Where( x => x.Father == null)
                          .TransformTree((person, childrenColl) => new
                          {
                              id = person.Id.ToString(),
                              text = person.Name + " " + person.LastName,
                              cls = "folder",
                              leaf = (person.HasChildren()),
                              children = childrenColl
                          }, person => person.Children);

return Json(query);
I hope you like it!

PS: I think you should avoid the anonymous type for testing purpose.

| More

 Akinator es un software que adivina en quien estas pensando. Como programador de aplicaciones me parece al menos curioso el funcionamiento (que estimo debe ser algo similar a prolog). Sin mas introducción, dejemos que esta imagen hable por si misma:

2009-05-16_0203

Es increíble que yo estuviera pensando en Wilson y que en un par de preguntas logrará adivinarlo, sin hacer preguntas obvias como: “¿su personaje es una pelota que vive en una isla?”.

| More

In my previous post I've talked about my ExtJs Grid helper. I want to show you in this post some samples. Lets start with the basic configuration. This is all you need to get an ExtJs Grid running. The first parameter of the SetDataStore method is the controller/action that returns the JSon data, the second parameter is the PK field. The WithAutoColumnModel method specifies that the grid must show a column for each property on the Person class. Let me add some custom columns: and this is what will be generated: So far so good, lets talk now about server-side paging. If you want paging support you have to add some parameters to the controller action (start and limit ) and return sliced data. You could take advantage of linq but I dont want to talk about that. Also, you need to make several changes to the view. It's a joke, just add WithPaging(pageSize) or just WithPaging() (whose default is 15) : ExtJs grid has support for custom column renderers. I wouldn't resolve this on the client-side, however: You could use this to create a custom cell format for a given value. There other options that I will skip: .WithLoadMask() .WithSizeOf(0, 300) .WithSelectionMode(SelectionMode.SingleSelect) Sorting is not yet supported. I hope you like this post and please drop me a mail if you are interested in this project.

| More

The goal of why I begun to write a "Helper" is very simple "Write less code". This is a basic configuration of ExtJs Grid with javascript. On the other hand, this is the code to configure it with my helper:

ExtGrid<person>.Start()
.WithLoadMask()
.WithAutoSize()
.WithPaging(20)
.WithSelectionMode(SelectionMode.SingleSelect)
.SetDataStore("Person/JsonList")
.Columns(colBuilder=>
        {
            colBuilder.For(x => x.Id).Named("Código");
            colBuilder.For(x => x.Descripcion).Named("Descripción");
            colBuilder.For(x => x.Id).LinksTo("Edit", "Person/Edit/{Id}");
        })
Almost all of these configurations are optional and have some overloads. So, How I've achieved this I've added another "level of indirection". Ext JS and JQuery frameworks use something called Joln (Javascript Object Literal Notation). This is like JSON but the member names are not quoted (more info here). Take a look to my other level of indirection For instance, this is a javascript configuration for JsonStore:
var store = new Ext.data.JsonStore({
url: 'get-images.php',
root: 'images'})
Then I wrote the following class:
public class ExtJsonStore : JsObject<ExtJsonStore{
public ExtJsonStore(string url){...}
public string Root { get; set; }
public string Url { get; set; }
protected override string GetJsClassName()
{
return "Ext.data.JsonStore";
}
protected override string GetConfiguratorConstructor()
{
return JolnBuilder.Start()
          .With("url", Url)
          .With("root", Root)
          .Build();
}
}
In this class the function called GetConfiguratorConstructor returns this string: {url: 'foo', root: 'bar'}. The abstract class JsObject has some methods as follows:
  • string CreateNewInstance() => return "new Ext.data.JsonStore({url: 'foo', root: 'bar'})"
  • JsObject CreateNewInstanceAndAssignToVar(string varName) => stack "var foo = new Ext.data.JsonStore({url: 'foo', root: 'bar'})"
  • JsObject WithMethodCall(string method) => stack "foo.doSomething()"
Finally this is a tdd spike! Don't use it in a real word application. Here is the project for download.

| More