我必须在网络服务中忽略某些内容......
数据结构:
TResIDNameRec = record
id : Integer;
name: String;
end;
TResIDNameArr = array of TResIDNameRec;
TResBase = class(TJSONStructure) // just a class(TObject)
private
public
&type : String;
success : Integer;
errormessage: String;
threadid : Integer;
constructor Create; overload; // empty
constructor Create(ADescendantClassName: String); overload; // sets &type
end;
TResClass = class of TResBase;
TResGetList = class(TResBase)
private
public
activities,
projects,
customers: TResIDNameArr;
constructor Create; overload; // inherited Create(Self.ClassName);
end;
然后是
type
TWebAct = (
ttlogin,
...
ttgetlist,
...
ttgetversion
);
const
cWebActStructures: Array[TWebAct] of
record
RequestClass : TReqClass;
ResponseClass: TResClass;
end
= (
{ ttlogin } (RequestClass: TReqLogin; ResponseClass: TResLogin;),
...
{ ttgetlist } (RequestClass: TReqGetList; ResponseClass: TResGetList;),
...
{ ttgetversion} (RequestClass: TReqGetVersion; ResponseClass: TResGetVersion;)
);
我的WebModule上有一个私有字段:
FResponse: TResBase; // Response object
在WebmoduleBeforeDispatch中,FWebAct是一个ttgetlist,我这样做:
lResponseClass := cWebActStructures[FWebAct].ResponseClass;
FResponse := lResponseClass.Create(lResponseClass.ClassName);
// FResponse.ClassName is TResGetList, OK
在处理'ttgetlist'的TWebActionItem的OnAction处理程序中,这是必不可少的部分:
var
lListArr : TResIDNameArr;
begin
lListArr := (FResponse as TResGetList).activities;
with AClientDataSet do
begin
Open;
SetLength(lListArr,RecordCount); // Pre-allocate (currently 152)
l := 0;
First;
while not EOF do
begin
if SomeConditionMet then
begin
lListArr[l].id := FieldByName(lIDVeld).AsInteger;
lListArr[l].name := FieldByName(SName).AsString;
Inc(l);
end;
Next;
end;
Close;
SetLength(lListArr,l+1); // Adjust (l is now 108)
end;
FResponse.success := 1;
lListArr此时显示正确的数据,对象检查器显示:
((3, 'Activiteit 3'), (4, 'Activiteit 3.1'), (5, 'Activiteit 3.2'), (10, 'Activiteit 3.3'), (8, 'Activiteit 5'),...
在WebmoduleAfterDispatch中:
var lJSO: ISuperObject;
begin
lJSO := FResponse.ToJson;
LJSO.AsString确实有正确的字段(& type,success,... activities,...),例如success = 1,但活动为空:
{
"errormessage":"",
"success":1,
"projects":[],
"threadid":1556,
"type":"ttgetlistresult",
"customers":[],
"activities":[]
}
我在俯瞰什么?也许OnAction处理程序中的lListArr := (FResponse as TResGetList).activities
不够好吗?
BTW随意更新问题标题,这是我能想到的最好的。
答案 0 :(得分:3)
分配lListArr
时,局部变量会将引用接收到activities
字段引用的同一个数组。但是,当您致电SetLength(lListArr, ...)
时,会使lListArr
引用 new 数组,与之前引用的数组完全分开。
如果希望字段引用同一个数组,则需要将其分配回字段:
(FResponse as TResGetList).activities := lListArr;
您可以在设置长度后随时进行该分配。通过任一变量都可以看到更改数组的内容。但是,更改长度与更改内容不同。更改长度会重新分配整个数组,并提供一个新的唯一数组。