状况:
我正在使用Desktop组件开发一个Ext.Net Web App,我在第一次创建Window时遇到了麻烦。
循环从“索引”视图开始,该视图只构建主桌面环境。在此视图中,创建了一个具有JS处理函数的模块,如下所示:
.Modules(
X.DesktopModule()
.ModuleID("ModuleTitle")
.Shortcut(
X.DesktopShortcut()
.Name("Module Title")
.IconCls("custom-icon")
.Handler("loadModuleWindow(Desktop,'AssetManager');")
)
处理程序函数“loadModuleWindow”然后有责任决定是否必须首次创建Window,或者是否已经创建了Window,只需要再次显示:
function loadModuleWindow(callingContainer, moduleId) {
//Dynamically build name of script by convention
loadScriptFile("Scripts/" + moduleId + "Scripts.js", "js");
//Only create new window if it hasn't been created already
if (App[moduleId] == undefined) {
App.direct.CreateModuleWindow(callingContainer.id, moduleId);
} else {
App[moduleId].show();
}
}
创建桌面并首次调用Module时,将调用代码隐藏方法“CreateModuleWindow”,并将Window返回给客户端。
窗口设置为:
window.CloseAction = CloseAction.Hide;
到目前为止一切正常,关闭窗口时会出现问题(点击它的[X]关闭按钮)。 正如预期的那样,窗口对当前视图是隐藏的,任务栏上的“指示符”也被删除。
正如您可能已经猜到的那样,使用Handler(“loadModuleWindow”)的目的是在Window加载一次之后避免服务器调用。
但是,当在这个窗口上调用方法Show()时,会发生两件事:
1)如果我在没有参数的情况下调用Show()方法,则没有任何反应。窗口保持隐藏状态,并且不会再显示在桌面上。
2)如果我调用Show(callerContainer.id)这样的方法给它一个目标,那么桌面上会显示Window,但是任务栏中的窗口“指示符”没有重新加载,我得到一个错误,说明“offsetWidth”属性未定义。
问题:
有没有人知道在使用CloseAction配置窗口时可以调用的任何其他方法=隐藏,以便在第一次创建时将其“恢复”到桌面?
** 更新:完整代码重现问题 的 ** * ** *
ENTRY POINT CONTROLLER(DektopController.cs)
[DirectController]
public class DesktopController : Controller
{
public ActionResult Index()
{
return View();
}
[DirectMethod(ShowMask = true)]
public ActionResult CreateModuleWindow(string callingContainerId, string moduleId)
{
//Only AJAX requests are allowed
if (Request.IsAjaxRequest() == true)
{
ControllerHelpers.CreateAndAttachWindow(this, callingContainerId, moduleId);
return this.Direct();
}
else //No direct URL access
{ return new EmptyResult(); }
}
}
控制器帮助
public static Window GetWindowViewModel(string moduleId)
{
// Dynamically instantiate the ViewModel class
// By convention, the ViewModel that creates the Window is named
// moduleName + "ViewModel".
// The ViewModel should also assign the moduleId to the window.ID
Type type = Type.GetType("App.Web.ViewModels." + moduleId + "ViewModel");
Object obj = Activator.CreateInstance(type);
return (Window)obj;
}
public static void CreateAndAttachWindow(Controller cont, string callingContainerId, string moduleId)
{
Desktop callingContainer = cont.GetCmp<Desktop>(callingContainerId);
Window moduleWindow = GetWindowViewModel(moduleId);
if (moduleWindow != null)
{
callingContainer.CreateWindow(moduleWindow);
}
}
RAZOR INDEX FILE
@model Ext.Net.Desktop
@{
ViewBag.Title = "Desktop";
Layout = "~/Views/Shared/_Desktop.cshtml";
var X = Html.X();
}
@(
X.Desktop()
.ID("MyDesktop")
.Listeners(l =>
{
l.Ready.BroadcastOnBus = "App.Desktop1.Ready";
})
.Modules(
X.DesktopModule()
.ModuleID("Module1")
.Shortcut(
X.DesktopShortcut()
.Name("Module 1")
.Handler("loadModuleWindow(App.MyDesktop,'Module1');")
)
)
)
“loadModuleWindow”JAVASCRIPT FILE
function loadModuleWindow(callingContainer, moduleId) {
//Only create new window if it hasn't been created already
if (App[moduleId] == undefined) {
App.direct.CreateModuleWindow(callingContainer.id, moduleId);
//Set the returned window to the module, by convention, the
//window.id is the same as the moduleId.
App[callingContainer.id].getModule(moduleId).setWindow(moduleId);
} else {
App[callingContainer.id].getModule(moduleId).run();
}
}
MODULE1查看模型文件
public class Module1ViewModel : Window
{
public Toolbar TopToolBar {get; private set;}
public TreePanel AssetHierarchy { get; private set; }
public Module1ViewModel()
{
this.ID = "Module1";
this.Title = "Module1";
this.Width = 1400;
this.Height = 600;
this.Layout = LayoutType.Border.ToString();
this.CloseAction = CloseAction.Hide;
this.Stateful = true;
}
}
答案 0 :(得分:0)
有一些问题。
首先,Module及其Window的ID必须是唯一的,它们是独立的组件。
因此,请更改,例如,在Module1ViewModel。
this.ID = "Module1_Window"
其次,Desktop的CreateWindow独立于任何模块显示一个Window,而setWindow调用不足以将Window附加到Module。我们应该有方便的方法将Window附加到模块,但是,目前我们没有这样的方法。目前,我可以建议以下解决方案。
将loadModuleWindow函数替换为:
function loadModuleWindow(callingContainer, moduleId) {
var module = App[callingContainer.id].getModule(moduleId);
if (!module.win) {
App.direct.CreateModuleWindow(moduleId, {
success: function (result) {
module.autoRun = true;
module.addWindow(function () { return eval(result)[0] });
}
});
} else {
module.run();
}
}
将CreateModuleWindow方法替换为:
[DirectMethod(ShowMask = true)]
public ActionResult CreateModuleWindow(string moduleId)
{
Window moduleWindow = GetWindowViewModel(moduleId);
moduleWindow.AutoRender = false;
string moduleWindowCfg = ComponentLoader.ToConfig(moduleWindow);
return this.Direct(moduleWindowCfg);
}
保留其他内容而不做任何更改。
有关设计的一些注意事项。
通常,桌面模块不支持动态附加窗口,因为模块应该用作Window的不可分割单元。这意味着模块需要为模块预定义Window。应该如何做。您可以创建一个窗口,而无需将其分配给任何模块,也可以动态创建整个模块。