【一起学UniGUI】--UniGUI的窗体和模块(8)-程序员宅基地

技术标签: UniGUI  

(六)、数据模块(DataModules):

       uniGUI支持向项目中添加数据模块(DataModules)。它允许开发人员像标准VCL应用程序那样设计他们的应用程序,将应用程序业务逻辑划分为几个数据模块。需要记住的重要一点是,虽然uniGUI数据模块与标准VCL数据模块在本质上是相同的,但是当使用uniGUI向导创建它们时,它们将为每个会话自动管理(其生存期将与会话本身相同)。如果使用标准IDE创建数据模型,则开发人员须要在适当的时候创建并释放它,并且有可能还是各会话共用(如果开发者不额外处理的话),须解决多会话间冲突问题。

      uniGUI中有两种类型的数据模块。 分别为:应用程序数据模块(Application DataModule) 与 自由数据模块(Free DataModule)。在下面的章节中,我会分子类进行讲述。

1)、应用程序数据模块(Application DataModule)

     应用程序数据模块(Application DataModule)是一个由uniGUI在运行时额外自动生成的,有如下几个特点:

  • 它在应用程序运行初始化时注册生成的
  • 它是在每个会话的开始或按需创建的(依据属性MainModule.ApplicationDataModuleOptions.CreateOnDemand),一个会话对应一个
  • 如果用户不手动释放(使用Free),则在关闭某对应会话时会相对应的自动释放(属于A会话的,在A会话关闭时,会自动释放A对应的应用程序数据模块)

       需要额外数据模型的小型应用程序(比如,多个MainModule)可能会使用缺省值(CreateOnDemand=False),但是大型应用程序将享受更好的内存管理,可以按需创建数据模型(并尽快释放它们)。

这是应用程序中DataModule自动生成的代码:

unit _AppDM1;
 
interface
 
uses
  SysUtils, Classes, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Param,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
  Data.DB, FireDAC.Comp.DataSet, FireDAC.Comp.Client, FireDAC.Stan.StorageBin;
 
type
  TAppDM1 = class(TDataModule)
    tblList: TFDMemTable;
    tblListID: TAutoIncField;
    tblListText: TStringField;
    dsList: TDataSource;
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
function AppDM1: TAppDM1;
 
implementation
 
{$R *.dfm}
 
uses
  UniGUIVars, uniGUIMainModule, MainModule;
 

// 这个函数返回一个TAppDM1数据模块实例

// MainModule.ApplicationDataModuleOptions.CreateOnDemandTrue,如果尚未创建datamodule实例,

// 这个函数将创建一个实例并返回给它,否则它将返回先前创建的实例。

// MainModule.ApplicationDataModuleOptions.CreateOnDemandFalse。这个函数在会话启动时直接创建相同的datamodule实例并将返回给它

function AppDM1: TAppDM1;
begin
  Result := TAppDM1(UniMainModule.GetModuleInstance(TAppDM1));
end;
 
initialization
  RegisterModuleClass(TAppDM1);
 
end.

     注意这段代码与应用程序窗体(Application Form)非常相似。
     如果将参数CreateOnDemand设置为true,让我们看看窗体将如何使用应用程序数据模块(Application DataModule)。

unit _TestForm;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, uniGUITypes, uniGUIAbstractClasses,
  uniGUIClasses, uniGUIForm,
  _AppDM1, uniGUIBaseClasses, uniBasicGrid, uniDBGrid;
 
type
  TTestForm = class(TUniForm)
    UniDBGrid1: TUniDBGrid;
    procedure UniFormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
function TestForm: TTestForm;
 
implementation
 
{$R *.dfm}
 
uses
  MainModule, uniGUIApplication;
 
function TestForm: TTestForm;
begin
  Result := TTestForm(UniMainModule.GetFormInstance(TTestForm));
end;
 
procedure TTestForm.UniFormDestroy(Sender: TObject);
begin
  AppDM1.Free;  //如果此数据模块(AppDM1)确实不再使用时或也没有其他窗体使用时,在这里写Free方法进行手工释放也是可以的(但不是必须)

                  //如果此数据模块(AppDM1)被占用了,或者同一会话中的其他几个窗体也使用了它,那么不应该调用Free方法

                  //如果这里没有调用Free方法,则在其所属的会话终止时也会自动释放此数据模块(AppDM1)

end;
 
end.

       在窗体OnDestroy销毁事件中显式进行datamodule释放(也就是说,当窗体不再需要它时)。但是没有代码将UniDBGrid链接到数据模块中。让我们来看看DFM文件:

object TestForm: TTestForm
  Left = 0
  Top = 0
  ClientHeight = 246
  ClientWidth = 477
  Caption = 'Test (using App DM On Demand)'
  OldCreateOrder = False
  MonitoredKeys.Keys = <>
  OnDestroy = UniFormDestroy
  PixelsPerInch = 96
  TextHeight = 13
  object UniDBGrid1: TUniDBGrid
    Left = 0
    Top = 0
    Width = 477
    Height = 246
    Hint = ''
    DataSource = AppDM1.dsList
    LoadMask.Message = 'Loading data...'
    Align = alClient
    Anchors = [akLeft, akTop, akRight, akBottom]
    TabOrder = 0
  end
end

该链接在表单设计器中也可见:

数据源(TDataSource)在设计时链接到数据模块。在运行时不需要这样做。
运行应用程序证明它确实在没有内存泄漏的情况下工作(内存不泄漏)。

2)、自由数据模块(Free DataModule) 

      这种自由数据模块型只是一个普通的旧数据模型,即与传统VCL的datamodule一样,须要手工创建和释放它。

unit _FreeDataModule;
 
interface
 
uses
  SysUtils, Classes;
 
type
  TFreeDataModule = class(TDataModule)
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
implementation
 
{$R *.dfm}
 
 
end.

       这种数据模块的使用方法与在常见VCL应用程序中使用的方法相同。用户完全有责任在需要时创建它,并在不再需要时释放它。 使用这种数据模型的原因是,一些非可视组件需要一个主机/容器(或者以这种方式使用它们更容易)。一个很好的例子是报表工具,因为即使用户只将它用于导出报表,它通常也会被放入一个DataModule中。
       使用数据模块的另一个原因是不应该在表示层(TForm、TUniForm、任何窗体)中承载“业务代码”。使用自由的数据模块(Free DataModule)允许开发人员按需处理资源,从而将内存使用量降到最低。
      自由数据模块的使用在FastReport和ReportBuilder等如何使用,我会在后面一些深入的学习中再讲述(计划在报表部分中讲解)。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/gzhubin/article/details/92060816

智能推荐

@property用法总结-程序员宅基地

1.当方法需要传入别的参数时,不能定义成@property.比如_table(self, owner)转载于:https://www.cnblogs.com/Stephen-Qin/p/10251083.html_@excelproperty 不出现在excel

八叉树 C++ 基础 源码_稀疏八叉树-程序员宅基地

http://blog.csdn.net/pizi0475/article/details/6269060四叉树或四元树也被称为Q树(Q-Tree)。四叉树广泛应用于图像处理、空间数据索引、2D中的快速碰撞检测、存储稀疏数据等,而八叉树(Octree)主要应用于3D图形处理。实际的数据结构,就是一个树根不断地往下扩,每次分成八个枝,直到叶子为止。 叶子节点代表了分辨率最高的情况。例如分辨率设成0._稀疏八叉树

吴恩达深度学习:池化层卷积神经网络示例_卷积池化计算题-程序员宅基地

此公众号会发表计算机考研(初复试信息)、夏令营等资料,方便考研人对信息的获取,节约自身查找资料的时间,回复408,可获得数据结构、操作系统、计算机网络、计算机组成原理全科资料构建全卷积神经网络的构造模块我们已经掌握得差不多了,下面来看个例子。假设,有一张大小为32×32×3的输入图片,这是一张RGB模式的图片,你想做手写体数字识别。32×32×3的RGB图片中含有某个数字,比如7,你想识别它是从0-9这10个数字中的哪一个,我们构建一个神经网络来实现这个功能。我用的这个网络模型和经典网络L.._卷积池化计算题

大整数除法的实现_大整数除法硬件实现-程序员宅基地

/* 基本的思想是反复做减法,看看从被除数里最多能减去多少个除数,商就是多少。一个减法显然太慢了,如何能减得更快呢? 以7546除以23为例来看一下:开始商为0。先减去23的100倍,就是2300,发现减3次,余下646。于是商的值就增加300.然后用 646减去230,发现减够2次,余下186,于是商的值增加20。最后用186减去23,够减8次,因此最终商就是328。 核心是要写一个大整_大整数除法硬件实现

如何快速的开发一个完整的iOS直播app-程序员宅基地

目录【如何快速的开发一个完整的iOS直播app】(原理篇)【如何快速的开发一个完整的iOS直播app】(播放篇)【如何快速的开发一个完整的iOS直播app】(采集篇)【如何快速的开发一个完整的iOS直播app】(美颜篇)【如何快速的开发一个完整的iOS直播app】(推流篇)【如何快速的开发一个完整的iOS直播app】(搭建web服务器)前言大...

STM32串口发送数据和接收数据方式总结(转)_stm32串口发送数字-程序员宅基地

之前写了篇关于ESP8266使用AT指令进行互相通讯的实验,在写STM32串口接发数据的程序中,觉得有必要将之前学的有关于串口方面的使用经历加以总结。串口发送数据:1. 串口发送数据最直接的方式就是标准调用库函数。void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);第一个参数是发送的串口号,第二个参数..._stm32串口发送数字

随便推点

举个栗子!Tableau 技巧(175):通过 URL 传参实现不同工作簿的跳转_tableau url 参数-程序员宅基地

在 Tableau 中实现跳转,我们之前分享过 ???? :通过 跳转 查看更多的地图详情 和 添加跳转按钮实现页面切换,数据粉可按需学习。实际分析场景中,考虑到仪表板性能,我们通常会将复杂的分析项目,用不同的工作簿来分类呈现。不同工作簿数据有一定关联性的时候,跳转查看就变得非常必要了。如何跨工作簿进行跳转呢?试试 URL 传参的方式。☟ 本栗子需要用到 Tableau Server,学习之前请准备好服务器环境哦~免费试用 Tableau Server拷贝以下链接到浏览器,免费下载试用最新版 S_tableau url 参数

PoE供电的三种标准你知道吗?_jiezhangxiaji的博客-程序员宅基地

今天给大家讲讲PoE系统和802.3af(PoE)、802.3at(PoE+)、802.3bt(PoE++)三种标准。PoE 全称为 Power Over Ethernet,PoE 又被称为基于局域网的供电系统(PoL, Power over LAN )或有源以太网( Active Ethernet),有时也被简称为以太网供电,这是利用现存标准,规范了以太网传输电缆在传送数据的同时,又满足供电的功率应用要求,并保持了与现存以太网系统和用户的兼容性。PoE的系统构成及供电特性参数一个完整的PoE系

2012服务器系统安装net3.5,Windows 8、Windows 8.1、Windows Server 2012和 Windows Server 2012 R2 上的 .NET Framewor..._花生妈的博客-程序员宅基地

通知本文介绍了不再需要或适用于任何当前客户需求的过时更新。 请不要下载和部署此更新。 本文仅作为存档参考发布。简介此更新解决了在安装 Microsoft .NET Framework 3.5 的安全更新 2966827 或 2966828(Microsoft 安全公告 MS14-046 中进行了介绍)后阻止启用可选的 Microsoft .NET Framework 3.5 功能的问题。此更新适用..._windows2966827 2966828

RMAN-06026,RMAN-06100-程序员宅基地

在恢复演练中,遇到过两次RMAN-06100错误,错误信息如下第一次的错误信息:RMAN-00571: ===========================================================RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============RMAN-00571:

win7 32位安装Python3.5问题-程序员宅基地

当我们在win7上安装python3.5时,可能会报如下错误: 这是因为api-ms-win-crt-runtime就是MFC的运行时环境的库,python在windows上编译也是用微软的visual studio C++编译的,底层也会用到微软提供的C++库和runtime库,安装Visual C++ Redistributable for Visual Studio 201

页面加载时,添加进度条,提高用户体验_前端页面加载数据响应时间大于3秒加进度条-程序员宅基地

这几个月做了个项目,在此对一些问题做一个记录。项目是前后端分离的,前端用的 npm+webpack。问题:由于系统某页面数据量过大或网络较差等原因,导致页面还未完全加载出来,但按钮已被加载时(js还未就绪),点击按钮会报错。根据系统情况,解决方案:每个页面加载的时候,在header上方加一个动态的进度条,同时通过css样式在页面上覆盖一个透明的背景,使页面在加载完成前不可点击。页面完全..._前端页面加载数据响应时间大于3秒加进度条