PDA

View Full Version : [CLOSED] MVC Custom Control using Builder framework - Loader problem



anup
Aug 12, 2012, 3:25 PM
Hi,

This question/problem builds on from this thread where Vladimir showed how a custom Ext.NET component can be exposed in MVC Razor using a class that implements IHtmlString: http://forums.ext.net/showthread.php?20432-CLOSED-Custom-Ext-NET-components-as-MVC-Helpers

The previous post is really handy but I wanted to go a step further. In the previous post I can do something like this with Razor:


@Html.FinancialGrid(400, 500);

But what I wanted to see if I could do is inherit/borrow from Ext.NET's own MVC framework so that I can get all the other properties/methods in Razor (e.g. .SetHeight(100).SetWidth(100).SetTitle("blah") etc)

So I gave it a go (using a custom window example). From an intellisense perspective, it worked, and I could do something like this:


@Html.MyApp().CustomWindow().SetHeight(100).SetWid th(150)

However, at run time it had an error saying the Loader could not load the corresponding JavaScript class, MyApp.CustomWindow.

Some code to reproduce:

1) CustomWindow class (C#)



public partial class CustomWindow : Window
{
internal const string JsResource = "Ext.Net2.Tests.CustomCode.CustomWindow.CustomWindo w.js";

public override string InstanceOf
{
get { return "MyApp.CustomWindow"; }
}

public override string XType
{
get { return "customwindow"; }
}

protected override List<ResourceItem> Resources
{
get
{
List<ResourceItem> baseList = base.Resources;
baseList.Capacity += 1;

baseList.Add(new ClientScriptItem(typeof(CustomWindow), JsResource, ""));

return baseList;
}
}

protected override void OnInit(EventArgs e)
{
Title = "My window";
Layout = "fit";
Border = false;
Items.Add(new Panel { Html = "Example" });

base.OnInit(e);
}
}


2) CustomWindow class (JavaScript)



Ext.define('MyApp.CustomWindow', {
extend: 'Ext.window.Window',

alias: 'customwindow'
});


3) JavaScript file is embedded into assembly

4) Example of it being successfully used in WebForms:


<cc1:CustomWindow runat="server" Height="100" Width="150" />

5) My attempt to build MVC support using your builder framework

a) Adding Builder support to Custom Window:



public partial class CustomWindow
{
public CustomWindow()
{
}

public CustomWindow(Config config)
{
Apply(config);
}

public Builder ToBuilder()
{
return new BuilderFactory().CustomWindow(this);
}

public class Builder : Builder<CustomWindow, Builder>
{
public Builder() : base(new CustomWindow()) { }

public Builder(CustomWindow component) : base(component) { }

public Builder(Config config) : base(new CustomWindow(config)) { }
}

new public class Config : Window.Config
{
public static implicit operator Builder(Config config)
{
return new Builder(config);
}
}
}


b) Adding a builder factory:



public partial class BuilderFactory
{
public HtmlHelper HtmlHelper { get; set; }
}

public partial class BuilderFactory
{
public CustomWindow.Builder CustomWindow()
{
return CustomWindow(new CustomWindow
{
ID = Guid.NewGuid().ToString("N"),
ViewContext = HtmlHelper != null ? HtmlHelper.ViewContext : null
});
}

public CustomWindow.Builder CustomWindow(CustomWindow component)
{
component.ViewContext = HtmlHelper != null ? HtmlHelper.ViewContext : null;
return new CustomWindow.Builder(component);
}
}


c) Creating a MyApp() namespace for MVC similar to your X() namespace.



public class MyApp
{
}

public static class MyAppExtensions
{
public static BuilderFactory MyApp(this HtmlHelper helper)
{
return new BuilderFactory { HtmlHelper = helper };
}
}


6) My Razor template:



@using Ext.Net2.Tests.CustomCode.CustomWindow
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
@Html.X().ResourceManager().Theme(Theme.Gray)

@Html.MyApp().CustomWindow().SetHeight(100).SetWid th(150)
</body>
</html>


Inside visual studio, Intellisense correctly offers me SetHeight, SetWidth and all the other various methods available.

However, if I browse the above template (assuming controller for it is created!) Firebug reports the following:

"Error: Ext.Loader is not enabled, so dependencies cannot be resolved dynamically. Missing required class: MyApp.CustomWindow"

When I look at the source code, indeed, the custom resource is not loaded (though it is if I use the WebForms approach -- or ControlRender approach as per the previous thread I mention at the top of this one).

Even if I add ResourceManager.RegisterControlResources&lt;CustomWin dow&gt;(); into the builder factory methods it still doesn't help.

Any thoughts? I've probably missed something when looking at your source code...

(Second question, I found I had to set the ID of the custom window - see where I used Guid.NewGuid(). If I didn't do that I got a different error saying Widget needs an ID. I couldn't see in your code how you addressed that without my "hack". Any insight into that would also be appreciated!)

Vladimir
Aug 12, 2012, 7:00 PM
About ID issue
SetHeight and SetWidth are methods (methods which generate javascript code). Those methods require ID for the widget because it generate javascript code like


App.WindowID.setHeight(50);


You have to use Width and Height properties


@Html.MyApp().CustomWindow().Height(100).Width(150 )

In this case, ID is not required


About resource issue, I cannot reproduce the problem, please ensure that
- resource path is correct
- js file is marked as Embedded resource
- WebResource attribute with resource name is added to AssemblyInfo.cs

For me, script tag for custom resource is generated and resource code is loaded correctly
Try to update from SVN and retest, may be you use old code (what revision do you use?)

anup
Aug 13, 2012, 10:28 AM
You have to use Width and Height properties


@Html.MyApp().CustomWindow().Height(100).Width(150 )

In this case, ID is not required


Thanks! Didn't realize that difference between Height and SetHeight! That worked. Also, now I see it, it also makes more sense to do it that way for Razor :)



About resource issue, I cannot reproduce the problem, please ensure that
- resource path is correct
- js file is marked as Embedded resource
- WebResource attribute with resource name is added to AssemblyInfo.cs

For me, script tag for custom resource is generated and resource code is loaded correctly
Try to update from SVN and retest, may be you use old code (what revision do you use?)

I was using SVN revision 4255. I see the latest is 4260. Just downloaded it and compiled but got this compilation error:



\2.1\Ext.Net\MVC\Ext\BaseControl.cs(30,29): error CS0102: The type 'Ext.Net.BaseControl' already contains a definition for 'IsMVC'
\2.1\Ext.Net\Core\BaseControl\Helpers.cs(38,29): (Related location)


I will try again later this afternoon when I get home from work.

As an aside, the resource path, embedded resource, web resource attribute etc are all correct because all code ran correctly in other usages (the Web Forms and Control Builder approach to MVC that I mentioned above). Using SetHeight() is my mistake. Maybe it caused a problem that prevented the rest of the Ext.NET code from being generated correctly, somehow because once I use Height() then everything works. But as you say maybe this goes away in later code.

Maybe you can assume it is not a problem anymore and once I get latest code that I build successfully I will let you know if there is still a problem.

Once again, thanks for such a prompt reply. Much appreciated.

Daniil
Aug 13, 2012, 12:35 PM
I was using SVN revision 4255. I see the latest is 4260. Just downloaded it and compiled but got this compilation error:



\2.1\Ext.Net\MVC\Ext\BaseControl.cs(30,29): error CS0102: The type 'Ext.Net.BaseControl' already contains a definition for 'IsMVC'
\2.1\Ext.Net\Core\BaseControl\Helpers.cs(38,29): (Related location)



Hi Anup,

Here is the related thread.
http://forums.ext.net/showthread.php?20486

Does it help?

anup
Aug 13, 2012, 5:52 PM
Thanks Daniil, that is exactly my problem. I too have the conditional compilation symbol set to ISPRO.

I can manually set it to MVC locally until it is updated in SVN. Thanks.

Vladimir
Aug 13, 2012, 6:05 PM
Ext.Net.csproj file in SVN already contains MVC conditional compilation symbol
I am not sure why you don't have it after update

anup
Aug 13, 2012, 8:57 PM
It looks to me this is an issue when in Release mode only. When compiling in Debug mode then it seems okay (it has "ISPRO MVC").

So I think it is just a matter of updating the Release build property.

(Also noticed that in Debug mode some warnings are suppressed but not in Release mode - dunno if that matters to you but thought I'd mention)

Vladimir
Aug 13, 2012, 9:02 PM
Thanks for the update. We will update Release mode

anup
Aug 14, 2012, 12:47 AM
Many thanks. I think this thread can be marked as closed then.