如何在TMS WEB Core中使用GetClass动态创建TWebFrame?

问题描述 投票:0回答:1

我创建了以下函数,用于创建

TWebFrame
并将其加载到我的表单中:

procedure LoadHomePage();
var
  FramePage: TWebFrame;
begin
  FramePage := TFrame_Home.Create(Self);

  FramePage.Name := 'layHome';
  FramePage.Visible := False;
  FramePage.Parent := LayoutContainer;
  FramePage.Align := alClient;
  FramePage.LoadFromForm;
end;

这可以正常工作,但我可能并不总是知道该页面的类是什么。假设我不知道该类是

TFrame_Home
,但我可以从某处以字符串形式获取
TFrame_Home
。如何在不知道类名是
TFrame_Home
的情况下动态创建同一页面?

我尝试使用

GetClass
函数来做到这一点,但它并没有真正起作用。这是我尝试过的:

procedure LoadHomePageDynamically();
var
  FrameClass: TPersistentClass;
  FramePage: TWebFrame;
begin
  FrameClass := GetClass('TFrame_Home');
  FramePage := TWebFrame(FrameClass.Create);

  FramePage.Name := 'layHome';
  FramePage.Visible := False;
  FramePage.Parent := LayoutContainer;
  FramePage.Align := alClient;
  FramePage.LoadFromForm;
end;

代码编译没有任何错误,但在运行时调用该函数时,出现以下错误:

未捕获的类型错误:无法读取 null 的属性(读取“appendChild”)| TypeError:无法在 Object.UpdateElement (http://localhost:8000/DelphiWebsite/DelphiWebsite.js:68452:32) 处读取 null 属性(读取“appendChild”)在 Object.EndUpdate (http://localhost:8000/DelphiWebsite) /DelphiWebsite.js:36935:43) 在 Object.EndUpdate (http://localhost:8000/DelphiWebsite/DelphiWebsite.js:37513:31) 在 Object.AfterLoadDFMValues (http://localhost:8000/DelphiWebsite/DelphiWebsite.js) :15413:12)在Object.LoadDFMValues(http://localhost:8000/DelphiWebsite/DelphiWebsite.js:85042:26)在Object.LoadFromForm(http://localhost:8000/DelphiWebsite/DelphiWebsite.js:45329:12) )在LoadHomePageDynamically(http://localhost:8000/DelphiWebsite/DelphiWebsite.js:101898:19)在Object.CreatePages(http://localhost:8000/DelphiWebsite/DelphiWebsite.js:101912:7)在Object.WebFormCreate( http://localhost:8000/DelphiWebsite/DelphiWebsite.js:101831:12) 在 Object.cb (http://localhost:8000/DelphiWebsite/DelphiWebsite.js:245:19) 在http://localhost:8000/DelphiWebsite/DelphiWebsite.js [68452:32]

因此,错误似乎来自

FramePage.LoadFromForm
代码,但我需要此代码才能加载框架并将其显示在表单上。

我还使用以下代码在框架的

.pas
文件底部注册了框架的类名:

initialization
  RegisterClasses([TFrame_Home]);

请注意,我对使用

GetClass
FindClass
和 RTTI 非常陌生。我还没有用它做很多事情。我也不确定我正在做的事情是否正确或可能。

我想使用

GetClass
这样做的原因是因为我可能有数百个不同的框架,并且我不想单独“硬编码”创建它们。因此,如果我可以使用类名来创建它们,那就完美了。


那么如何在不知道类名的情况下动态创建

TWebFrame
呢?

class delphi rtti tms-web-core delphi-12-athens
1个回答
0
投票

您的

LoadHomePage
LoadHomePageDynamically
正在调用不同的构造函数。第一个是从
TComponent
(或类似的类层次结构)调用虚拟构造函数,该构造函数将所有者作为参数,第二个是调用基类
TObject
构造函数,因为
TPersistent
类没有任何其他构造函数。

因此,当您调用

TWebFrame(FrameClass.Create)
时,您最终会得到不正确初始化的
TWebFrame
实例,因为您不会调用适当的虚拟构造函数,因此会出现您所看到的错误。

要调用适当的构造函数,您需要声明

TWebFrameClass
元类,它将能够调用适当的构造函数并正确初始化您的 Web 框架实例。

type
  TWebFrameClass = class of TWebFrame;

procedure LoadHomePageDynamically();
var
  FrameClass: TWebFrameClass;
  FramePage: TWebFrame;
begin
  FrameClass := TWebFrameClass(GetClass('TFrame_Home'));
  FramePage := FrameClass.Create(Self);

  FramePage.Name := 'layHome';
  FramePage.Visible := False;
  FramePage.Parent := LayoutContainer;
  FramePage.Align := alClient;
  FramePage.LoadFromForm;
end;

如果

TWebFrame
TComponent
后代,您也可以使用
TComponentClass
,而不是声明
TWebFrameClass
。但是,在这种情况下,您将需要在
FrameClass.Create(Self);
周围使用类型转换。将框架实例分配给
FramePage
变量时。

© www.soinside.com 2019 - 2024. All rights reserved.