mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-15 07:45:54 +01:00
Added ToMVCList to wrap any object and try to use as list
This commit is contained in:
parent
b0ccc9a974
commit
6bdf5547bc
@ -74,8 +74,9 @@ Congratulations to Daniele Teti and all the staff for the excellent work!" -- Ma
|
||||
|
||||
> WARNING! Considering the huge amount of features added in 3.1.1-beryllium during its RC phase, the dmvcframework-3.1.1-beryllium has been renamed to dmvcframework-3.2.0-boron
|
||||
|
||||
- New! Added Swagger support (thanks to [João Antônio Duarte]() and [Geoffrey Smith](https://github.com/geoffsmith82))
|
||||
- New! Added Swagger support (thanks to [João Antônio Duarte](https://github.com/joaoduarte19) and [Geoffrey Smith](https://github.com/geoffsmith82))
|
||||
- New! Added SQLGenerator and RQL compiler for PostgreSQL, SQLite and MSSQLServer (in addition to MySQL, MariaDB, Firebird and Interbase)
|
||||
- New! Added support for interfaces serialization - now it is possible to serialize Spring4D collections (thanks to [João Antônio Duarte](https://github.com/joaoduarte19))
|
||||
- Improved! Greatly improved support for [HATEOAS](https://en.wikipedia.org/wiki/HATEOAS) in renders. Check `TRenderSampleController.GetPeople_AsObjectList_HATEOS` and all the others actions end with `HATEOS` in `renders.dproj` sample)
|
||||
|
||||
```delphi
|
||||
|
@ -59,6 +59,39 @@ type
|
||||
class function GetList(const aCount: Integer = 3): TObjectList<TPerson>;
|
||||
end;
|
||||
|
||||
IPerson = interface
|
||||
['{1D00C67A-A6D9-4B31-8291-705B339CDE9B}']
|
||||
function GetName: String;
|
||||
procedure SetName(const Value: String);
|
||||
function GetAge: Integer;
|
||||
procedure SetAge(const Value: Integer);
|
||||
function GetDOB: TDate;
|
||||
procedure SetDOB(const Value: TDate);
|
||||
property Name: String read GetName write SetName;
|
||||
property Age: Integer read GetAge write SetAge;
|
||||
property DOB: TDate read GetDOB write SetDOB;
|
||||
end;
|
||||
|
||||
[MVCNameCase(ncCamelCase)]
|
||||
TInterfacedPerson = class(TInterfacedObject, IPerson)
|
||||
private
|
||||
fName: string;
|
||||
FDOB: TDate;
|
||||
fAge: Integer;
|
||||
protected
|
||||
function GetName: String;
|
||||
procedure SetName(const Value: String);
|
||||
function GetAge: Integer;
|
||||
procedure SetAge(const Value: Integer);
|
||||
function GetDOB: TDate;
|
||||
procedure SetDOB(const Value: TDate);
|
||||
public
|
||||
property Name: String read GetName write SetName;
|
||||
property Age: Integer read GetAge write SetAge;
|
||||
property DOB: TDate read GetDOB write SetDOB;
|
||||
end;
|
||||
|
||||
|
||||
TPeople = class(TObjectList<TPerson>);
|
||||
|
||||
[MVCNameCase(ncLowerCase)]
|
||||
@ -91,7 +124,7 @@ type
|
||||
[MVCNameCase(ncLowerCase)]
|
||||
TCustomer = class
|
||||
private
|
||||
FName: string;
|
||||
fName: string;
|
||||
FAddressLine2: string;
|
||||
FAddressLine1: string;
|
||||
FContactFirst: string;
|
||||
@ -108,7 +141,7 @@ type
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
property Name: string read FName write SetName;
|
||||
property Name: string read fName write SetName;
|
||||
[MVCDoNotSerialize]
|
||||
property ContactFirst: string read FContactFirst write SetContactFirst;
|
||||
[MVCDoNotSerialize]
|
||||
@ -185,14 +218,13 @@ begin
|
||||
Result := TObjectList<TPerson>.Create(true);
|
||||
for I := 1 to aCount do
|
||||
begin
|
||||
Result.Add(TPerson.GetNew(GetRndFirstName, GetRndLastName, EncodeDate(1900 + Random(100),
|
||||
Random(12) + 1, Random(27) + 1), true));
|
||||
Result.Add(TPerson.GetNew(GetRndFirstName, GetRndLastName, EncodeDate(1900 + Random(100), Random(12) + 1,
|
||||
Random(27) + 1), true));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
class function TPerson.GetNew(AFirstName, ALastName: string; ADOB: TDate;
|
||||
AMarried: boolean): TPerson;
|
||||
class function TPerson.GetNew(AFirstName, ALastName: string; ADOB: TDate; AMarried: boolean): TPerson;
|
||||
begin
|
||||
Result := TPerson.Create;
|
||||
Result.FLastName := ALastName;
|
||||
@ -302,7 +334,7 @@ end;
|
||||
|
||||
procedure TCustomer.SetName(const Value: string);
|
||||
begin
|
||||
FName := Value;
|
||||
fName := Value;
|
||||
end;
|
||||
|
||||
{ TProgrammer }
|
||||
@ -352,6 +384,38 @@ begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
{ TInterfacedPerson }
|
||||
|
||||
function TInterfacedPerson.GetAge: Integer;
|
||||
begin
|
||||
Result := fAge;
|
||||
end;
|
||||
|
||||
function TInterfacedPerson.GetDOB: TDate;
|
||||
begin
|
||||
Result := FDOB;
|
||||
end;
|
||||
|
||||
function TInterfacedPerson.GetName: String;
|
||||
begin
|
||||
Result := fName;
|
||||
end;
|
||||
|
||||
procedure TInterfacedPerson.SetAge(const Value: Integer);
|
||||
begin
|
||||
fAge := Value;
|
||||
end;
|
||||
|
||||
procedure TInterfacedPerson.SetDOB(const Value: TDate);
|
||||
begin
|
||||
FDOB := Value;
|
||||
end;
|
||||
|
||||
procedure TInterfacedPerson.SetName(const Value: String);
|
||||
begin
|
||||
fName := Value;
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
||||
Randomize;
|
||||
|
@ -8,6 +8,7 @@ uses
|
||||
|
||||
function GetPeopleList: TObjectList<TPerson>;
|
||||
function GetPeopleSmallList: TObjectList<TPerson>;
|
||||
function GetInterfacedPeopleList: TList<IPerson>;
|
||||
|
||||
implementation
|
||||
|
||||
@ -17,6 +18,23 @@ uses
|
||||
var
|
||||
GPeople, GPeopleSmall: TObjectList<TPerson>;
|
||||
|
||||
function GetInterfacedPeopleList: TList<IPerson>;
|
||||
var
|
||||
lPerson: IPerson;
|
||||
begin
|
||||
Result := TList<IPerson>.Create;
|
||||
lPerson := TInterfacedPerson.Create;
|
||||
lPerson.Name := 'Daniele Teti';
|
||||
lPerson.Age := 40;
|
||||
lPerson.DOB := EncodeDate(1979, 11, 4);
|
||||
Result.Add(lPerson);
|
||||
lPerson := TInterfacedPerson.Create;
|
||||
lPerson.Name := 'Peter Parker';
|
||||
lPerson.Age := 35;
|
||||
lPerson.DOB := EncodeDate(1984, 11, 4);
|
||||
Result.Add(lPerson);
|
||||
end;
|
||||
|
||||
procedure PopulateList;
|
||||
var
|
||||
p: TPerson;
|
||||
|
@ -39,8 +39,7 @@ type
|
||||
[MVCPath('/')]
|
||||
TRenderSampleController = class(TMVCController)
|
||||
protected
|
||||
procedure OnBeforeAction(AContext: TWebContext; const AActionName: string;
|
||||
var AHandled: Boolean); override;
|
||||
procedure OnBeforeAction(AContext: TWebContext; const AActionName: string; var AHandled: Boolean); override;
|
||||
public
|
||||
[MVCHTTPMethod([httpGET])]
|
||||
[MVCPath('/customers/($ID)')]
|
||||
@ -79,6 +78,11 @@ type
|
||||
[MVCProduces('application/json')]
|
||||
procedure GetPeople_AsObjectList;
|
||||
|
||||
[MVCHTTPMethod([httpGET])]
|
||||
[MVCPath('/interfacedpeople')]
|
||||
[MVCProduces('application/json')]
|
||||
procedure GetInterfacedPeople;
|
||||
|
||||
[MVCHTTPMethod([httpGET])]
|
||||
[MVCPath('/people/hateoas')]
|
||||
[MVCProduces('application/json')]
|
||||
@ -289,8 +293,7 @@ begin
|
||||
end;
|
||||
Context.Response.ContentType := TMVCMediaType.APPLICATION_OCTET_STREAM;
|
||||
Context.Response.StatusCode := HTTP_STATUS.OK;
|
||||
Context.Response.CustomHeaders.Values['Content-Disposition'] := 'attachment; filename=' +
|
||||
filename + ';';
|
||||
Context.Response.CustomHeaders.Values['Content-Disposition'] := 'attachment; filename=' + filename + ';';
|
||||
Render(TFileStream.Create(lFullFilePath, fmOpenRead or fmShareDenyNone));
|
||||
end;
|
||||
|
||||
@ -330,8 +333,7 @@ begin
|
||||
// We need a non standard representation, let's create a specific serializer.
|
||||
lSer := TMVCJsonDataObjectsSerializer.Create;
|
||||
try
|
||||
lSer.DataSetToJsonArray(lDM.qryCustomers, lJObj.a['customers'],
|
||||
TMVCNameCase.ncLowerCase, []);
|
||||
lSer.DataSetToJsonArray(lDM.qryCustomers, lJObj.a['customers'], TMVCNameCase.ncLowerCase, []);
|
||||
lSer.DataSetToJsonArray(lDM.qryCountry, lJObj.a['countries'], TMVCNameCase.ncLowerCase, []);
|
||||
finally
|
||||
lSer.Free;
|
||||
@ -369,22 +371,17 @@ begin
|
||||
Render(lDM.qryCustomers, False,
|
||||
procedure(const DS: TDataset; const Links: IMVCLinks)
|
||||
begin
|
||||
Links.AddRefLink
|
||||
.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString)
|
||||
.Add(HATEOAS.REL, 'self')
|
||||
.Add(HATEOAS._TYPE, 'application/json');
|
||||
Links.AddRefLink
|
||||
.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString + '/orders')
|
||||
.Add(HATEOAS.REL, 'orders')
|
||||
Links.AddRefLink.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString).Add(HATEOAS.REL, 'self')
|
||||
.Add(HATEOAS._TYPE, 'application/json');
|
||||
Links.AddRefLink.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString + '/orders')
|
||||
.Add(HATEOAS.REL, 'orders').Add(HATEOAS._TYPE, 'application/json');
|
||||
end);
|
||||
finally
|
||||
lDM.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TRenderSampleController.GetCustomer_AsDataSetRecord(
|
||||
const ID: Integer);
|
||||
procedure TRenderSampleController.GetCustomer_AsDataSetRecord(const ID: Integer);
|
||||
var
|
||||
lDM: TMyDataModule;
|
||||
begin
|
||||
@ -394,13 +391,9 @@ begin
|
||||
Render(lDM.qryCustomers, False, [], dstSingleRecord,
|
||||
procedure(const DS: TDataset; const Links: IMVCLinks)
|
||||
begin
|
||||
Links.AddRefLink
|
||||
.Add(HATEOAS.HREF, '/customers')
|
||||
.Add(HATEOAS.REL, 'customers')
|
||||
.Add(HATEOAS._TYPE, TMVCMediaType.APPLICATION_JSON);
|
||||
Links.AddRefLink
|
||||
.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString)
|
||||
.Add(HATEOAS.REL, 'self')
|
||||
Links.AddRefLink.Add(HATEOAS.HREF, '/customers').Add(HATEOAS.REL, 'customers').Add(HATEOAS._TYPE,
|
||||
TMVCMediaType.APPLICATION_JSON);
|
||||
Links.AddRefLink.Add(HATEOAS.HREF, '/customers/' + DS.FieldByName('cust_no').AsString).Add(HATEOAS.REL, 'self')
|
||||
.Add(HATEOAS._TYPE, TMVCMediaType.APPLICATION_JSON);
|
||||
end);
|
||||
finally
|
||||
@ -432,6 +425,11 @@ begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TRenderSampleController.GetInterfacedPeople;
|
||||
begin
|
||||
Render(ToMVCList(GetInterfacedPeopleList, True));
|
||||
end;
|
||||
|
||||
procedure TRenderSampleController.GetLotOfPeople;
|
||||
begin
|
||||
Render<TPerson>(GetPeopleList, False);
|
||||
@ -439,10 +437,8 @@ end;
|
||||
|
||||
procedure TRenderSampleController.GetPerson_AsHTML;
|
||||
begin
|
||||
ResponseStream.Append('<html><body><ul>').Append('<li>FirstName: Daniele</li>')
|
||||
.Append('<li>LastName: Teti')
|
||||
.AppendFormat('<li>DOB: %s</li>', [DateToISODate(EncodeDate(1975, 5, 2))])
|
||||
.Append('<li>Married: yes</li>')
|
||||
ResponseStream.Append('<html><body><ul>').Append('<li>FirstName: Daniele</li>').Append('<li>LastName: Teti')
|
||||
.AppendFormat('<li>DOB: %s</li>', [DateToISODate(EncodeDate(1975, 5, 2))]).Append('<li>Married: yes</li>')
|
||||
.Append('</ul></body></html>');
|
||||
RenderResponseStream;
|
||||
end;
|
||||
@ -472,11 +468,8 @@ end;
|
||||
|
||||
procedure TRenderSampleController.GetPerson_AsText(const ID: Integer);
|
||||
begin
|
||||
ResponseStream
|
||||
.AppendLine('ID : ' + ID.ToString)
|
||||
.AppendLine('FirstName : Daniele')
|
||||
.AppendLine('LastName : Teti')
|
||||
.AppendLine('DOB : ' + DateToStr(EncodeDate(1979, 5, 2)))
|
||||
ResponseStream.AppendLine('ID : ' + ID.ToString).AppendLine('FirstName : Daniele')
|
||||
.AppendLine('LastName : Teti').AppendLine('DOB : ' + DateToStr(EncodeDate(1979, 5, 2)))
|
||||
.AppendLine('Married : yes');
|
||||
RenderResponseStream;
|
||||
end;
|
||||
@ -627,15 +620,9 @@ begin
|
||||
Render<TPerson>(People, True,
|
||||
procedure(const APerson: TPerson; const Links: IMVCLinks)
|
||||
begin
|
||||
Links.AddRefLink
|
||||
.Add(HATEOAS.HREF, '/people/' + APerson.ID.ToString)
|
||||
.Add(HATEOAS.REL, 'self')
|
||||
.Add(HATEOAS._TYPE, 'application/json')
|
||||
.Add('title', 'Details for ' + APerson.FullName);
|
||||
Links.AddRefLink
|
||||
.Add(HATEOAS.HREF, '/people')
|
||||
.Add(HATEOAS.REL, 'people')
|
||||
.Add(HATEOAS._TYPE, 'application/json');
|
||||
Links.AddRefLink.Add(HATEOAS.HREF, '/people/' + APerson.ID.ToString).Add(HATEOAS.REL, 'self').Add(HATEOAS._TYPE,
|
||||
'application/json').Add('title', 'Details for ' + APerson.FullName);
|
||||
Links.AddRefLink.Add(HATEOAS.HREF, '/people').Add(HATEOAS.REL, 'people').Add(HATEOAS._TYPE, 'application/json');
|
||||
end);
|
||||
end;
|
||||
|
||||
@ -653,14 +640,10 @@ begin
|
||||
Render(lPerson, False,
|
||||
procedure(const AObject: TObject; const Links: IMVCLinks)
|
||||
begin
|
||||
Links.AddRefLink
|
||||
.Add(HATEOAS.HREF, '/people/' + TPerson(AObject).ID.ToString)
|
||||
.Add(HATEOAS.REL, 'self')
|
||||
.Add(HATEOAS._TYPE, TMVCMediaType.APPLICATION_JSON);
|
||||
Links.AddRefLink
|
||||
.Add(HATEOAS.HREF, '/people')
|
||||
.Add(HATEOAS.REL, 'people')
|
||||
Links.AddRefLink.Add(HATEOAS.HREF, '/people/' + TPerson(AObject).ID.ToString).Add(HATEOAS.REL, 'self')
|
||||
.Add(HATEOAS._TYPE, TMVCMediaType.APPLICATION_JSON);
|
||||
Links.AddRefLink.Add(HATEOAS.HREF, '/people').Add(HATEOAS.REL, 'people').Add(HATEOAS._TYPE,
|
||||
TMVCMediaType.APPLICATION_JSON);
|
||||
end);
|
||||
finally
|
||||
lPerson.Free;
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{8CCDACDA-3FA5-486E-AD8E-63E4113177EE}</ProjectGuid>
|
||||
<ProjectVersion>18.6</ProjectVersion>
|
||||
<ProjectVersion>18.7</ProjectVersion>
|
||||
<FrameworkType>None</FrameworkType>
|
||||
<MainSource>renders.dpr</MainSource>
|
||||
<Base>True</Base>
|
||||
@ -89,6 +89,11 @@
|
||||
<Android_LauncherIcon144>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png</Android_LauncherIcon144>
|
||||
<AUP_INTERNET>true</AUP_INTERNET>
|
||||
<Android_LauncherIcon48>$(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png</Android_LauncherIcon48>
|
||||
<Android_NotificationIcon24>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_24x24.png</Android_NotificationIcon24>
|
||||
<Android_NotificationIcon36>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_36x36.png</Android_NotificationIcon36>
|
||||
<Android_NotificationIcon48>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_48x48.png</Android_NotificationIcon48>
|
||||
<Android_NotificationIcon72>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_72x72.png</Android_NotificationIcon72>
|
||||
<Android_NotificationIcon96>$(BDS)\bin\Artwork\Android\FM_NotificationIcon_96x96.png</Android_NotificationIcon96>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win32)'!=''">
|
||||
<Manifest_File>None</Manifest_File>
|
||||
@ -317,6 +322,12 @@
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\renders\default.txvpck" Configuration="Release" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libPCRE.dylib" Class="DependencyModule">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Overwrite>true</Overwrite>
|
||||
@ -328,19 +339,13 @@
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\renders\default.txaPackage" Configuration="Debug" Class="ProjectFile">
|
||||
<DeployFile LocalName="ModelSupport_renders\renders1\default.txvpck" Configuration="Release" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\renders\default.txvpck" Configuration="Debug" Class="ProjectFile">
|
||||
<Platform Name="Linux64">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\RenderSampleControllerU\default.txaPackage" Configuration="Release" Class="ProjectFile">
|
||||
<DeployFile LocalName="ModelSupport_renders\renders\default.txaPackage" Configuration="Debug" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
@ -352,13 +357,13 @@
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\renders1\default.txvpck" Configuration="Release" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<DeployFile LocalName="ModelSupport_renders\renders\default.txvpck" Configuration="Debug" Class="ProjectFile">
|
||||
<Platform Name="Linux64">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\renders\default.txvpck" Configuration="Release" Class="ProjectFile">
|
||||
<DeployFile LocalName="ModelSupport_renders\RenderSampleControllerU\default.txaPackage" Configuration="Release" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
@ -560,6 +565,12 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_Colors">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_DefaultAppIcon">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
@ -596,6 +607,36 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon24">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-mdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon36">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-hdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon48">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon72">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_NotificationIcon96">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xxxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage426">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-small</RemoteDir>
|
||||
@ -620,6 +661,12 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_Strings">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DebugSymbols">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
@ -718,6 +765,17 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch1024x768">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch1536">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
@ -729,6 +787,39 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch1536x2048">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch1668">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch1668x2388">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch2048">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
@ -740,6 +831,61 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch2048x1536">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch2048x2732">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch2224">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch2388x1668">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch2732x2048">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch768">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
@ -751,6 +897,116 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch768x1024">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch1125">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch1136x640">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch1242">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch1242x2688">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch1334">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch1792">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch2208">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch2436">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch2688x1242">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch320">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
@ -784,6 +1040,28 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch750">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch828">
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectAndroidManifest">
|
||||
<Platform Name="Android">
|
||||
<Operation>1</Operation>
|
||||
|
@ -1,18 +1,34 @@
|
||||
// ***************************************************************************
|
||||
//
|
||||
// Delphi MVC Framework
|
||||
//
|
||||
// Copyright (c) 2010-2019 Daniele Teti and the DMVCFramework Team
|
||||
//
|
||||
// https://github.com/danieleteti/delphimvcframework
|
||||
//
|
||||
// ***************************************************************************
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// *************************************************************************** }
|
||||
|
||||
unit MVCFramework.Console;
|
||||
|
||||
interface
|
||||
|
||||
type
|
||||
TConsoleMode = (Normal, Bright);
|
||||
TConsoleColor = (
|
||||
Black = 30,
|
||||
Red = 31,
|
||||
Green = 32,
|
||||
Yellow = 33,
|
||||
Blue = 34,
|
||||
Magenta = 35,
|
||||
Cyan = 36,
|
||||
White = 37);
|
||||
TConsoleColor = (Black = 30, Red = 31, Green = 32, Yellow = 33, Blue = 34, Magenta = 35, Cyan = 36, White = 37);
|
||||
|
||||
procedure ResetConsole;
|
||||
procedure TextColor(const Color: TConsoleColor);
|
||||
@ -23,12 +39,10 @@ implementation
|
||||
|
||||
uses
|
||||
|
||||
{$IFDEF MSWINDOWS}
|
||||
|
||||
{$IFDEF MSWINDOWS}
|
||||
WinApi.Windows,
|
||||
|
||||
{$ENDIF}
|
||||
|
||||
{$ENDIF}
|
||||
System.SysUtils;
|
||||
|
||||
const
|
||||
@ -37,7 +51,7 @@ const
|
||||
var
|
||||
GForeGround: TConsoleColor;
|
||||
GBackGround: TConsoleColor;
|
||||
GMode: TConsoleMode = TConsolemode.Normal;
|
||||
GMode: TConsoleMode = TConsoleMode.Normal;
|
||||
|
||||
function ToBackGround(const ForeGround: Byte): Byte;
|
||||
begin
|
||||
|
@ -292,11 +292,16 @@ begin
|
||||
raise EMVCDuckTypingException.Create
|
||||
('Cannot find method Indexed property "Items" or method "GetItem" or method "GetElement" in the Duck Object.');
|
||||
lValue := FGetItemMethod.Invoke(FObjectAsDuck, [AIndex]);
|
||||
if not lValue.IsObject then
|
||||
|
||||
if lValue.Kind = tkInterface then
|
||||
begin
|
||||
raise EMVCDuckTypingException.Create('Items in list can be only objects');
|
||||
Exit(TObject(lValue.AsInterface));
|
||||
end;
|
||||
Result := lValue.AsObject;
|
||||
if lValue.Kind = tkClass then
|
||||
begin
|
||||
Exit(lValue.AsObject);
|
||||
end;
|
||||
raise EMVCDuckTypingException.Create('Items in list can be only objects or interfaces');
|
||||
end;
|
||||
|
||||
function TDuckTypedList.GetOwnsObjects: Boolean;
|
||||
|
@ -221,6 +221,11 @@ var
|
||||
LEnumPrefix: string;
|
||||
LEnumName: string;
|
||||
begin
|
||||
if SameText(AName, 'RefCount') then
|
||||
begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if AValue.IsEmpty then
|
||||
begin
|
||||
AJsonObject[AName] := Null;
|
||||
@ -1369,9 +1374,8 @@ begin
|
||||
LIgnoredAttrs := TList<string>.Create;
|
||||
try
|
||||
LIgnoredAttrs.AddRange(AIgnoredAttributes);
|
||||
if Assigned(GetRttiContext.GetType(TObject(AObject).ClassType).GetProperty('RefCount')) then
|
||||
LIgnoredAttrs.Add('RefCount');
|
||||
|
||||
// if Assigned(GetRttiContext.GetType(TObject(AObject).ClassType).GetProperty('RefCount')) then
|
||||
// LIgnoredAttrs.Add('RefCount');
|
||||
Result := SerializeObject(TObject(AObject), AType, TMVCIgnoredList(LIgnoredAttrs.ToArray), ASerializationAction);
|
||||
finally
|
||||
LIgnoredAttrs.Free;
|
||||
|
@ -601,6 +601,7 @@ type
|
||||
FContext: TWebContext;
|
||||
FContentCharset: string;
|
||||
FResponseStream: TStringBuilder;
|
||||
function ToMVCList(const AObject: TObject; AOwnsObject: Boolean = False): IMVCList;
|
||||
public
|
||||
function GetContentType: string;
|
||||
function GetStatusCode: Integer;
|
||||
@ -3060,6 +3061,11 @@ begin
|
||||
GetContext.Response.StatusCode := AValue;
|
||||
end;
|
||||
|
||||
function TMVCRenderer.ToMVCList(const AObject: TObject; AOwnsObject: Boolean): IMVCList;
|
||||
begin
|
||||
Result := MVCFramework.DuckTyping.WrapAsList(AObject,AOwnsObject);
|
||||
end;
|
||||
|
||||
procedure TMVCController.SetViewData(const aModelName: string; const Value: TObject);
|
||||
begin
|
||||
GetViewModel.Add(aModelName, Value);
|
||||
|
Loading…
Reference in New Issue
Block a user