diff --git a/samples/serversideviews_lua/MVCFramework.View.Renderers.Lua.pas b/samples/serversideviews_lua/MVCFramework.View.Renderers.Lua.pas index 5c34dc27..13d77e3f 100644 --- a/samples/serversideviews_lua/MVCFramework.View.Renderers.Lua.pas +++ b/samples/serversideviews_lua/MVCFramework.View.Renderers.Lua.pas @@ -87,7 +87,7 @@ procedure TMVCLuaViewEngine.Execute(const ViewName: string; const OutputStream: TStream); var Lua: TLuaEngine; - lDataSetName, lModelName: string; + lModelName: string; lLuaFilter: TLuaEmbeddedTextFilter; lViewFileName: String; lFileName, lCompiledFileName: string; @@ -158,13 +158,6 @@ begin end; end; end; - if Assigned(ViewDataSets) then - begin - for lDataSetName in ViewDataSets.Keys do - begin - ExposeDataSet(Lua, ViewDataSets[lDataSetName], ViewDataSets[lDataSetName].Name); - end; - end; Lua.DeclareGlobalString('__ROOT__', ExtractFilePath(ParamStr(0))); Lua.DeclareGlobalString('__log_file', LOG_FILE_NAME); diff --git a/samples/serversideviews_lua/ServerSideViewsLua.dproj b/samples/serversideviews_lua/ServerSideViewsLua.dproj index cd1d6d8c..634df04d 100644 --- a/samples/serversideviews_lua/ServerSideViewsLua.dproj +++ b/samples/serversideviews_lua/ServerSideViewsLua.dproj @@ -1,7 +1,7 @@  {C829684B-145E-49F2-8C37-2562C6C5904E} - 19.5 + 20.1 VCL ServerSideViewsLua.dpr True @@ -216,6 +216,16 @@ 1 + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + res\values @@ -236,6 +246,66 @@ 1 + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + res\values @@ -246,6 +316,16 @@ 1 + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + res\drawable @@ -416,6 +496,56 @@ 1 + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + 1 diff --git a/samples/serversideviews_mustache/ServerSideViewsMustache.dproj b/samples/serversideviews_mustache/ServerSideViewsMustache.dproj index b3f2ddac..5e973554 100644 --- a/samples/serversideviews_mustache/ServerSideViewsMustache.dproj +++ b/samples/serversideviews_mustache/ServerSideViewsMustache.dproj @@ -1,7 +1,7 @@  {C829684B-145E-49F2-8C37-2562C6C5904E} - 19.5 + 20.1 VCL ServerSideViewsMustache.dpr True @@ -218,6 +218,16 @@ 1 + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + res\values @@ -238,6 +248,66 @@ 1 + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + res\values @@ -248,6 +318,16 @@ 1 + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + res\drawable @@ -418,6 +498,56 @@ 1 + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + 1 diff --git a/samples/serversideviews_mustache/WebModuleU.dfm b/samples/serversideviews_mustache/WebModuleU.dfm index 632294be..4dc736c0 100644 --- a/samples/serversideviews_mustache/WebModuleU.dfm +++ b/samples/serversideviews_mustache/WebModuleU.dfm @@ -9,4 +9,15 @@ object WebModule1: TWebModule1 end> Height = 230 Width = 415 + object FDMemTable1: TFDMemTable + FetchOptions.AssignedValues = [evMode] + FetchOptions.Mode = fmAll + ResourceOptions.AssignedValues = [rvSilentMode] + ResourceOptions.SilentMode = True + UpdateOptions.AssignedValues = [uvCheckRequired, uvAutoCommitUpdates] + UpdateOptions.CheckRequired = False + UpdateOptions.AutoCommitUpdates = True + Left = 192 + Top = 96 + end end diff --git a/samples/serversideviews_mustache/WebModuleU.pas b/samples/serversideviews_mustache/WebModuleU.pas index 980057e8..d1fece5a 100644 --- a/samples/serversideviews_mustache/WebModuleU.pas +++ b/samples/serversideviews_mustache/WebModuleU.pas @@ -2,10 +2,13 @@ unit WebModuleU; interface -uses System.SysUtils, System.Classes, Web.HTTPApp, MVCFramework; +uses System.SysUtils, System.Classes, Web.HTTPApp, MVCFramework, 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; type TWebModule1 = class(TWebModule) + FDMemTable1: TFDMemTable; procedure WebModuleCreate(Sender: TObject); procedure WebModuleDestroy(Sender: TObject); private diff --git a/samples/serversideviews_mustache/WebSiteControllerU.pas b/samples/serversideviews_mustache/WebSiteControllerU.pas index 522493be..1b5bb416 100644 --- a/samples/serversideviews_mustache/WebSiteControllerU.pas +++ b/samples/serversideviews_mustache/WebSiteControllerU.pas @@ -60,13 +60,20 @@ type [MVCHTTPMethods([httpGET])] [MVCProduces(TMVCMediaType.TEXT_HTML)] function MustacheTemplateShowCase: String; + + [MVCPath('/loadviewtest')] + [MVCHTTPMethods([httpGET])] + [MVCProduces(TMVCMediaType.TEXT_PLAIN)] + procedure LoadViewTest; end; implementation { TWebSiteController } -uses System.SysUtils, Web.HTTPApp; +uses System.SysUtils, Web.HTTPApp, 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; procedure TWebSiteController.DeletePerson; var @@ -146,6 +153,30 @@ begin Redirect('/people'); end; +procedure TWebSiteController.LoadViewTest; +var + lDS: TFDMemTable; +begin + lDS := TFDMemTable.Create(nil); + try + lDS.FieldDefs.Add('id', ftInteger); + lDS.FieldDefs.Add('first_name', ftString, 40); + lDS.FieldDefs.Add('last_name', ftString, 40); + lDS.FieldDefs.Add('age', ftInteger); + lDS.CreateDataSet; + lDS.AppendRecord([1,'Daniele','Teti',44]); + lDS.AppendRecord([2,'Bruce','Banner',54]); + lDS.AppendRecord([3,'Peter','Parker',34]); + lDS.First; + + ViewData['people'] := lDS; + LoadView(['people_list_test','people_list_test']); + RenderResponseStream; + finally + lDS.Free; + end; +end; + function TWebSiteController.MustacheTemplateShowCase: String; var LDAL: IPeopleDAL; @@ -204,7 +235,7 @@ begin inherited; SetPagesCommonHeaders(['header']); SetPagesCommonFooters(['footer']); - ContentType := 'text/html'; + if not AActionNAme.ToLower.Contains('test') then ContentType := 'text/html'; Handled := False; end; diff --git a/samples/serversideviews_mustache/bin/templates/people_list_test.mustache b/samples/serversideviews_mustache/bin/templates/people_list_test.mustache new file mode 100644 index 00000000..2a7e7960 --- /dev/null +++ b/samples/serversideviews_mustache/bin/templates/people_list_test.mustache @@ -0,0 +1,4 @@ +LIST +{{#people}} +- {{id}};"{{first_name}}";"{{last_name}}";{{age}} +{{/people}} diff --git a/samples/serversideviews_sempare/ServerSideViewsSempare.dproj b/samples/serversideviews_sempare/ServerSideViewsSempare.dproj index fd3fbca1..5dfd42c6 100644 --- a/samples/serversideviews_sempare/ServerSideViewsSempare.dproj +++ b/samples/serversideviews_sempare/ServerSideViewsSempare.dproj @@ -1,7 +1,7 @@  {FE6AE7E7-2089-4ACF-B85D-3443EE2CCFE4} - 19.5 + 20.1 VCL ServerSideViewsSempare.dpr True @@ -272,6 +272,16 @@ 1 + + + res\drawable-anydpi-v21 + 1 + + + res\drawable-anydpi-v21 + 1 + + res\values @@ -292,6 +302,66 @@ 1 + + + res\values-v31 + 1 + + + res\values-v31 + 1 + + + + + res\drawable-anydpi-v26 + 1 + + + res\drawable-anydpi-v26 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-anydpi-v33 + 1 + + + res\drawable-anydpi-v33 + 1 + + res\values @@ -302,6 +372,16 @@ 1 + + + res\values-night-v21 + 1 + + + res\values-night-v21 + 1 + + res\drawable @@ -472,6 +552,56 @@ 1 + + + res\drawable-anydpi-v24 + 1 + + + res\drawable-anydpi-v24 + 1 + + + + + res\drawable + 1 + + + res\drawable + 1 + + + + + res\drawable-night-anydpi-v21 + 1 + + + res\drawable-night-anydpi-v21 + 1 + + + + + res\drawable-anydpi-v31 + 1 + + + res\drawable-anydpi-v31 + 1 + + + + + res\drawable-night-anydpi-v31 + 1 + + + res\drawable-night-anydpi-v31 + 1 + + 1 diff --git a/sources/MVCFramework.View.Renderers.Mustache.pas b/sources/MVCFramework.View.Renderers.Mustache.pas index 0d7b27b4..147e2aec 100644 --- a/sources/MVCFramework.View.Renderers.Mustache.pas +++ b/sources/MVCFramework.View.Renderers.Mustache.pas @@ -40,6 +40,7 @@ type strict private procedure PrepareModels; private + fModelPrepared: Boolean; class var fPartials: TSynMustachePartials; class var fHelpers: TSynMustacheHelpers; class var fSerializerPool: IIntfObjectPool; @@ -53,7 +54,6 @@ type procedure Execute(const ViewName: string; const OutputStream: TStream); override; constructor Create(const AEngine: TMVCEngine; const AWebContext: TWebContext; const AViewModel: TMVCViewDataObject; - const AViewDataSets: TObjectDictionary; const AContentType: string); override; class destructor Destroy; class constructor Create; @@ -101,10 +101,10 @@ var constructor TMVCMustacheViewEngine.Create(const AEngine: TMVCEngine; const AWebContext: TWebContext; const AViewModel: TMVCViewDataObject; - const AViewDataSets: TObjectDictionary; const AContentType: string); begin inherited; + fModelPrepared := False; LoadPartials; LoadHelpers; end; @@ -218,61 +218,56 @@ end; procedure TMVCMustacheViewEngine.PrepareModels; var DataObj: TPair; - lDSPair: TPair; lSer: IMVCSerializer; lJSONModel: TJsonObject; begin - if Assigned(FJSONModel) and (not Assigned(ViewModel)) and (not Assigned(ViewDataSets)) then + if fModelPrepared then begin - // if only jsonmodel is <> nil then we take the "fast path" - FJSONModelAsString := FJSONModel.ToJSON(False); Exit; end; - - - lSer := fSerializerPool.GetFromPool(True) as IMVCSerializer; - try - if Assigned(FJSONModel) then - begin - lJSONModel := FJSONModel.Clone as TJsonObject; - end - else - begin - lJSONModel := TJsonObject.Create; - end; + if Assigned(FJSONModel) and (not Assigned(ViewModel)) then + begin + // if only jsonmodel is <> nil then we take the "fast path" + FJSONModelAsString := FJSONModel.ToJSON(False); + end + else + begin + lSer := fSerializerPool.GetFromPool(True) as IMVCSerializer; try - if Assigned(ViewModel) then + if Assigned(FJSONModel) then begin - for DataObj in ViewModel do - begin - TMVCJsonDataObjectsSerializer(lSer).TValueToJSONObjectProperty(lJSONModel, DataObj.Key, DataObj.Value, TMVCSerializationType.stDefault, nil, nil); - // lList := TDuckTypedList.Wrap(DataObj.Value); - // if lList <> nil then - // begin - // lSer.ListToJsonArray(lList, lJSONModel.A[DataObj.Key], TMVCSerializationType.stProperties, nil); - // end - // else - // begin - // lSer.ObjectToJsonObject(DataObj.Value, lJSONModel.O[DataObj.Key], TMVCSerializationType.stProperties, nil); - // end; - end; + lJSONModel := FJSONModel.Clone as TJsonObject; + end + else + begin + lJSONModel := TJsonObject.Create; end; + try + if Assigned(ViewModel) then + begin + for DataObj in ViewModel do + begin + TMVCJsonDataObjectsSerializer(lSer).TValueToJSONObjectProperty(lJSONModel, DataObj.Key, DataObj.Value, TMVCSerializationType.stDefault, nil, nil); + end; + end; - if Assigned(ViewDataSets) then - begin - for lDSPair in ViewDataSets do - begin - TMVCJsonDataObjectsSerializer(lSer).DataSetToJsonArray(lDSPair.Value, lJSONModel.A[lDSPair.Key], TMVCNameCase.ncAsIs, nil); - end; +// if Assigned(ViewDataSets) then +// begin +// for lDSPair in ViewDataSets do +// begin +// TMVCJsonDataObjectsSerializer(lSer).DataSetToJsonArray(lDSPair.Value, lJSONModel.A[lDSPair.Key], TMVCNameCase.ncAsIs, nil); +// end; +// end; + FJSONModelAsString := lJSONModel.ToJSON(False); + finally + lJSONModel.Free; end; - FJSONModelAsString := lJSONModel.ToJSON(False); finally - lJSONModel.Free; + fSerializerPool.ReleaseToPool(lSer) end; - finally - fSerializerPool.ReleaseToPool(lSer) end; + fModelPrepared := True; end; { dmvcframework specific helpers} diff --git a/sources/MVCFramework.pas b/sources/MVCFramework.pas index e9d4fdfc..c683a24a 100644 --- a/sources/MVCFramework.pas +++ b/sources/MVCFramework.pas @@ -782,14 +782,11 @@ type TMVCController = class(TMVCRenderer) private FViewModel: TMVCViewDataObject; - FViewDataSets: TMVCViewDataSet; fPageHeaders: TArray; fPageFooters: TArray; function GetSession: TMVCWebSession; function GetViewData(const aModelName: string): TValue; - function GetViewDataset(const aDataSetName: string): TDataSet; procedure SetViewData(const aModelName: string; const Value: TValue); - procedure SetViewDataset(const aDataSetName: string; const Value: TDataSet); protected const CLIENTID_KEY = '__clientid'; protected @@ -803,7 +800,6 @@ type function GetClientId: string; function GetCurrentWebModule: TWebModule; function GetViewModel: TMVCViewDataObject; - function GetViewDataSets: TMVCViewDataSet; function GetRenderedView(const AViewNames: TArray): string; overload; virtual; function GetRenderedView(const AViewNames: TArray; const JSONModel: TJSONObject): string; overload; virtual; @@ -867,13 +863,8 @@ type property StatusCode: Integer read GetStatusCode write SetStatusCode; procedure PushObjectToView(const aModelName: string; const AModel: TObject); deprecated 'Use "ViewData"'; - procedure PushDataSetToView(const aModelName: string; const ADataSet: TDataSet); - deprecated 'Use "ViewDataSet"'; property ViewData[const aModelName: string]: TValue read GetViewData write SetViewData; - property ViewDataset[const aDataSetName: string]: TDataSet read GetViewDataset - write SetViewDataset; - public constructor Create; virtual; destructor Destroy; override; @@ -1199,7 +1190,6 @@ type FViewName: string; FWebContext: TWebContext; FViewModel: TMVCViewDataObject; - FViewDataSets: TObjectDictionary; FContentType: string; FOutput: string; protected @@ -1209,13 +1199,11 @@ type public constructor Create(const AEngine: TMVCEngine; const AWebContext: TWebContext; const AViewModel: TMVCViewDataObject; - const AViewDataSets: TObjectDictionary; const AContentType: string); overload; virtual; constructor Create( const AEngine: TMVCEngine; const AWebContext: TWebContext; const AViewModel: TMVCViewDataObject; - const AViewDataSets: TObjectDictionary; const AJSONModel: TJSONObject; const AContentType: string); overload; virtual; destructor Destroy; override; @@ -1225,7 +1213,6 @@ type property ViewName: string read FViewName; property WebContext: TWebContext read FWebContext; property ViewModel: TMVCViewDataObject read FViewModel; - property ViewDataSets: TObjectDictionary read FViewDataSets; property ContentType: string read FContentType; property Output: string read FOutput; end; @@ -3793,7 +3780,6 @@ begin FContentCharset := TMVCConstants.DEFAULT_CONTENT_CHARSET; FResponseStream := nil; FViewModel := nil; - FViewDataSets := nil; fPageHeaders := nil; fPageFooters := nil; end; @@ -3802,12 +3788,8 @@ destructor TMVCController.Destroy; begin if Assigned(FResponseStream) then FResponseStream.Free; - if Assigned(FViewModel) then FViewModel.Free; - - if Assigned(FViewDataSets) then - FViewDataSets.Free; inherited Destroy; end; @@ -3853,7 +3835,7 @@ var begin lStrStream := TStringStream.Create('', TEncoding.UTF8); try - lView := FEngine.ViewEngineClass.Create(Engine, Context, FViewModel, FViewDataSets, JSONModel, ContentType); + lView := FEngine.ViewEngineClass.Create(Engine, Context, FViewModel, JSONModel, ContentType); try for lViewName in AViewNames do begin @@ -3913,19 +3895,6 @@ begin Result := nil; end; -function TMVCController.GetViewDataset(const aDataSetName: string): TDataSet; -begin - if not FViewDataSets.TryGetValue(aDataSetName, Result) then - Result := nil; -end; - -function TMVCController.GetViewDataSets: TMVCViewDataSet; -begin - if not Assigned(FViewDataSets) then - FViewDataSets := TMVCViewDataSet.Create; - Result := FViewDataSets; -end; - function TMVCController.GetViewModel: TMVCViewDataObject; begin if not Assigned(FViewModel) then @@ -3999,11 +3968,6 @@ begin Result := GetRenderedView(AViewNames); end; -procedure TMVCController.PushDataSetToView(const aModelName: string; const ADataSet: TDataSet); -begin - GetViewDataSets.Add(aModelName, ADataSet); -end; - procedure TMVCController.PushObjectToView(const aModelName: string; const AModel: TObject); begin GetViewModel.Add(aModelName, AModel); @@ -4234,11 +4198,6 @@ begin GetViewModel.Add(aModelName, Value); end; -procedure TMVCController.SetViewDataset(const aDataSetName: string; const Value: TDataSet); -begin - GetViewDataSets.Add(aDataSetName, Value); -end; - procedure TMVCRenderer.Render( const AObject: TObject; const AOwns: Boolean; @@ -4412,7 +4371,7 @@ begin try lView := FEngine.ViewEngineClass.Create( Engine, Context, - FViewModel, FViewDataSets, + FViewModel, ContentType); try for lViewName in AViewNames do @@ -4793,14 +4752,12 @@ constructor TMVCBaseViewEngine.Create( const AEngine: TMVCEngine; const AWebContext: TWebContext; const AViewModel: TMVCViewDataObject; - const AViewDataSets: TObjectDictionary; const AContentType: string); begin inherited Create; Engine := AEngine; FWebContext := AWebContext; FViewModel := AViewModel; - FViewDataSets := AViewDataSets; FContentType := AContentType; FOutput := EmptyStr; end; @@ -4809,11 +4766,10 @@ constructor TMVCBaseViewEngine.Create( const AEngine: TMVCEngine; const AWebContext: TWebContext; const AViewModel: TMVCViewDataObject; - const AViewDataSets: TObjectDictionary; const AJSONModel: TJSONObject; const AContentType: string); begin - Create(AEngine, AWebContext, AViewModel, AViewDataSets, AContentType); + Create(AEngine, AWebContext, AViewModel, AContentType); fJSONModel := AJSONModel; end;