浏览代码

* Added events to influence streaming process

git-svn-id: trunk@15859 -
michael 15 年之前
父节点
当前提交
43256c7f14
共有 2 个文件被更改,包括 129 次插入18 次删除
  1. 72 9
      packages/fcl-web/src/webdata/extjsjson.pp
  2. 57 9
      packages/fcl-web/src/webdata/extjsxml.pp

+ 72 - 9
packages/fcl-web/src/webdata/extjsjson.pp

@@ -5,7 +5,7 @@ unit extjsjson;
 interface
 
 uses
-  Classes, SysUtils, httpdefs, fphttp,fpwebdata, fpextjs, fpjson, db, jsonparser;
+  Classes, SysUtils, httpdefs, fphttp, fpwebdata, fpextjs, fpjson, db, jsonparser;
 
 type
 
@@ -23,10 +23,16 @@ type
     Function TryFieldValue(Const AFieldName : String; out AValue : String) : Boolean; override;
     Destructor destroy; override;
   end;
-  { TExtJSJSONDataFormatter }
 
+  { TExtJSJSONDataFormatter }
+  TJSONObjectEvent = Procedure(Sender : TObject; AObject : TJSONObject) of Object;
   TExtJSJSONDataFormatter = Class(TExtJSDataFormatter)
   private
+    FAfterDataToJSON: TJSONObjectEvent;
+    FAfterRowToJSON: TJSONObjectEvent;
+    FBeforeDataToJSON: TJSONObjectEvent;
+    FBeforeRowToJSON: TJSONObjectEvent;
+    FOnMetaDataToJSON: TJSONObjectEvent;
     procedure SendSuccess(ResponseContent: TStream; AddIDValue : Boolean = False);
   protected
     Function CreateAdaptor(ARequest : TRequest) : TCustomWebdataInputAdaptor; override;
@@ -34,11 +40,27 @@ type
     function GetDataContentType: String; override;
     Function GetJSONMetaData: TJSONObject;
     function RowToJSON: TJSONObject;
+    Procedure DoBeforeRow(ARow : TJSONObject); virtual;
+    Procedure DoAfterRow(ARow : TJSONObject); virtual;
+    Procedure DoBeforeData(AResponse : TJSONObject); virtual;
+    Procedure DoAfterData(AResponse : TJSONObject); virtual;
+    Procedure DoOnMetaData(AMetadata : TJSONObject); virtual;
     procedure DatasetToStream(Stream: TStream); override;
     Procedure DoExceptionToStream(E : Exception; ResponseContent : TStream); override;
     Procedure DoInsertRecord(ResponseContent : TStream); override;
     Procedure DoUpdateRecord(ResponseContent : TStream); override;
     Procedure DoDeleteRecord(ResponseContent : TStream); override;
+  Published
+    // Called before any fields are added to row object (passed to handler).
+    Property AfterRowToJSON : TJSONObjectEvent Read FAfterRowToJSON Write FAfterRowToJSON;
+    // Called After all fields are added to row object (passed to handler).
+    Property BeforeRowToJSON : TJSONObjectEvent Read FBeforeRowToJSON Write FBeforeRowToJSON;
+    // Called when metadata object has been created (passed to handler).
+    Property OnMetaDataToJSON : TJSONObjectEvent Read FOnMetaDataToJSON Write FOnMetaDataToJSON;
+    // Called when response object has been created, and has Rows property (response passed to handler).
+    Property AfterDataToJSON : TJSONObjectEvent Read FAfterDataToJSON Write FAfterDataToJSON;
+    // Called just before response object will be streamed (response passed to handler).
+    Property BeforeDataToJSON : TJSONObjectEvent Read FBeforeDataToJSON Write FBeforeDataToJSON;
   end;
 
 implementation
@@ -117,11 +139,48 @@ Var
 
 begin
   Result:=TJSONObject.Create();
-  For I:=0 to Dataset.Fields.Count-1 do
-    begin
-    F:=Dataset.Fields[I];
-    AddFieldToJSON(Result,F.FieldName,F);
-    end;
+  try
+    DobeforeRow(Result);
+    For I:=0 to Dataset.Fields.Count-1 do
+      begin
+      F:=Dataset.Fields[I];
+      AddFieldToJSON(Result,F.FieldName,F);
+      end;
+    DoAfterRow(Result);
+  except
+    Result.Free;
+    Raise;
+  end;
+end;
+
+procedure TExtJSJSONDataFormatter.DoBeforeRow(ARow: TJSONObject);
+begin
+  If Assigned(FBeforeRowToJSON) then
+    FBeforeRowToJSON(Self,ARow);
+end;
+
+procedure TExtJSJSONDataFormatter.DoAfterRow(ARow: TJSONObject);
+begin
+  If Assigned(FAfterRowToJSON) then
+    FAfterRowToJSON(Self,ARow);
+end;
+
+procedure TExtJSJSONDataFormatter.DoBeforeData(AResponse: TJSONObject);
+begin
+  If Assigned(FBeforeDataToJSON) then
+    FBeforeDataToJSON(Self,AResponse);
+end;
+
+procedure TExtJSJSONDataFormatter.DoAfterData(AResponse: TJSONObject);
+begin
+  If Assigned(FAfterDataToJSON) then
+    FAfterDataToJSON(Self,AResponse);
+end;
+
+procedure TExtJSJSONDataFormatter.DoOnMetaData(AMetadata: TJSONObject);
+begin
+  If Assigned(FOnMetaDataToJSON) then
+    FOnMetaDataToJSON(Self,AMetaData);
 end;
 
 Function TExtJSJSONDataFormatter.GetJSONMetaData: TJSONObject;
@@ -200,7 +259,8 @@ begin
     Result.Add(SIdProperty,Provider.IDFieldName);
     Result.Add(SSuccessProperty, SuccessProperty);
     Result.Add(SRootProperty, RowsProperty);
-    Result.Add(STotalProperty, totalProperty)
+    Result.Add(STotalProperty, totalProperty);
+    DoOnMetaData(Result);
   except
     Result.free;
     Raise;
@@ -221,6 +281,8 @@ begin
   Resp:=TJSONObject.Create;
   try
     Rows:=TJSONArray.Create();
+    Resp.Add(RowsProperty,Rows);
+    DoBeforeData(Resp);
     DS:=Dataset;
     DS.First;
     RCount:=0;
@@ -251,10 +313,10 @@ begin
         Inc(RCount);
         DS.Next;
         end;
-    Resp.Add(RowsProperty,Rows);
     Resp.Add(SuccessProperty,True);
     If (PageSize>0) then
        Resp.Add(TotalProperty,RCount);
+    DoAfterData(Resp);
     L:=Resp.AsJSON;
     Stream.WriteBuffer(L[1],Length(L));
   finally
@@ -280,6 +342,7 @@ begin
     L:=Resp.AsJSON;
     If Length(L)>0 then
       ResponseContent.WriteBuffer(L[1],Length(L));
+    Resp.Add(RowsProperty,TJSONArray.Create());
   finally
     Resp.Free;
   end;

+ 57 - 9
packages/fcl-web/src/webdata/extjsxml.pp

@@ -37,9 +37,13 @@ Type
   { TExtJSJSONDataFormatter }
 
   { TExtJSXMLDataFormatter }
-
+  TXMLElementEvent = Procedure (Sender : TObject; AElement : TDOMElement) of object;
   TExtJSXMLDataFormatter = Class(TExtJSDataFormatter)
   private
+    FAfterDataToXML: TXMLElementEvent;
+    FAfterRowToXML: TXMLElementEvent;
+    FBeforeDataToXML: TXMLElementEvent;
+    FBeforeRowToXML: TXMLElementEvent;
     FDP: String;
     FReP: String;
     FRP: String;
@@ -51,6 +55,10 @@ Type
     Procedure DoExceptionToStream(E : Exception; ResponseContent : TStream); override;
     Function GetDataContentType : String; override;
     function RowToXML(Doc: TXMLDocument): TDOMelement;
+    Procedure DoBeforeRow(ARow : TDOMElement); virtual;
+    Procedure DoAfterRow(ARow : TDOMElement); virtual;
+    Procedure DoBeforeData(Data : TDOMElement); virtual;
+    Procedure DoAfterData(Data: TDOMElement); virtual;
     procedure DatasetToStream(Stream: TStream); override;
   public
     Constructor Create(AOwner : TComponent); override;
@@ -58,6 +66,14 @@ Type
     Property RootProperty : String Read FRP Write FRP Stored IsRootStored;
     Property RecordProperty : String Read FReP Write FReP Stored IsRecordStored;
     Property DocumentProperty : String Read FDP Write FDP Stored IsDocumentStored;
+    // Called before row element (passed to handler) is filled with fields.
+    Property BeforeRowToXML : TXMLElementEvent Read FBeforeRowToXML Write FBeforeRowToXML;
+    // Called after row element (passed to handler) was filled with fields.
+    Property AfterRowToXML : TXMLElementEvent Read FAfterRowToXML Write FAfterRowToXML;
+    // Called before any rows are added to root element (passed to handler).
+    Property BeforeDataToXML : TXMLElementEvent Read FBeforeDataToXML Write FBeforeDataToXML;
+    // Called after all rows are appended to root element (passed to handler).
+    Property AfterDataToXML : TXMLElementEvent Read FAfterDataToXML Write FAfterDataToXML;
   end;
 
 implementation
@@ -151,13 +167,44 @@ Var
   I : Integer;
 begin
   Result:=Doc.CreateElement(RecordProperty);
-  For I:=0 to Dataset.Fields.Count-1 do
-    begin
-    F:=Dataset.Fields[i];
-    E:=Doc.CreateElement(F.FieldName);
-    E.AppendChild(Doc.CreateTextNode(F.DisplayText));
-    Result.AppendChild(E);
-    end;
+  try
+    DoBeforeRow(Result);
+    For I:=0 to Dataset.Fields.Count-1 do
+      begin
+      F:=Dataset.Fields[i];
+      E:=Doc.CreateElement(F.FieldName);
+      E.AppendChild(Doc.CreateTextNode(F.DisplayText));
+      Result.AppendChild(E);
+      end;
+    DoAfterRow(Result);
+  except
+    Result.Free;
+    Raise;
+  end;
+end;
+
+procedure TExtJSXMLDataFormatter.DoBeforeRow(ARow: TDOMElement);
+begin
+  If Assigned(FBEforeRowToXml) then
+    FBEforeRowToXml(Self,ARow);
+end;
+
+procedure TExtJSXMLDataFormatter.DoAfterRow(ARow: TDOMElement);
+begin
+  If Assigned(FAfterRowToXml) then
+    FAfterRowToXml(Self,ARow);
+end;
+
+procedure TExtJSXMLDataFormatter.DoBeforeData(Data: TDOMElement);
+begin
+  If Assigned(FBeforeDataToXML) then
+    FBeforeDataToXML(Self,Data);
+end;
+
+procedure TExtJSXMLDataFormatter.DoAfterDAta(Data: TDOMElement);
+begin
+  If Assigned(FAfterDataToXML) then
+    FAfterDataToXML(Self,Data);
 end;
 
 procedure TExtJSXMLDataFormatter.DatasetToStream(Stream: TStream);
@@ -176,6 +223,7 @@ begin
    try
      E:=XML.CreateElement(RootProperty);
      XML.AppendChild(E);
+     DoBeforeData(E);
      // Go to start
      ACount:=PageStart;
      While (Not DS.EOF) and (ACount>0) do
@@ -204,8 +252,8 @@ begin
      C:=XML.CreateElement(SuccessProperty);
      C.AppendChild(XML.CreateTextNode('true'));
      E.AppendChild(C);
+     DoAfterData(E);
      WriteXMLFile(XML,Stream);
-
    finally
      XML.Free;
    end;