Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 8 of 8 total
Thread TPersistent.AfterLoad
Mon, Apr 24 2017 6:00 AMPermanent Link

Matthew Jones

Here's an interesting one. I think that TPersistent should be calling AfterLoad for all objects it creates, including children. I have a complex object (TDetailItem) that is stored in a list contained by another object (TBigObject). The logical place to do the "I've finished loading" code is in the TDetailItem AfterLoad, but it is never called, because it is a child of TBigItem and it is that which gets the AfterLoad.

Now, you could argue that this is the better way, so the whole object is loaded before it is done, but that then stops the TDetailItem being created and processed by a smaller JSON packet not part of TBigObject.

Thoughts?

--

Matthew Jones
Tue, Apr 25 2017 2:42 AMPermanent Link

MarkB

I agree.  Pretty sure I reported this quite some time ago.


"Matthew Jones" wrote:

Here's an interesting one. I think that TPersistent should be calling AfterLoad for all objects it creates, including children. I have a complex object (TDetailItem) that is stored in a list contained by another object (TBigObject). The logical place to do the "I've finished loading" code is in the TDetailItem AfterLoad, but it is never called, because it is a child of TBigItem and it is that which gets the AfterLoad.

Now, you could argue that this is the better way, so the whole object is loaded before it is done, but that then stops the TDetailItem being created and processed by a smaller JSON packet not part of TBigObject.

Thoughts?

--

Matthew Jones
Tue, Apr 25 2017 2:43 AMPermanent Link

MarkB

http://www.elevatesoft.com/forums?action=view&category=ewb&id=ewb2_preview&msg=653&start=1&keywords=MarkB&searchbody=True&forum=EWB_Announce&forum=EWB_General&forum=EWB_Components&forum=EWB_Server&forum=EWB_Demos&forum=EWB_Binaries&forum=EWB_Discussion&forum=EWB2_Preview&forum=EWB_Beta#653


"Matthew Jones" wrote:

Here's an interesting one. I think that TPersistent should be calling AfterLoad for all objects it creates, including children. I have a complex object (TDetailItem) that is stored in a list contained by another object (TBigObject). The logical place to do the "I've finished loading" code is in the TDetailItem AfterLoad, but it is never called, because it is a child of TBigItem and it is that which gets the AfterLoad.

Now, you could argue that this is the better way, so the whole object is loaded before it is done, but that then stops the TDetailItem being created and processed by a smaller JSON packet not part of TBigObject.

Thoughts?

--

Matthew Jones
Tue, Apr 25 2017 6:28 AMPermanent Link

Matthew Jones

MarkB wrote:

> http://www.elevatesoft.com/forums?action=view&category=ewb&id=ewb2_preview&msg=653&start=1&keywords=MarkB&searchbody=True&forum=EWB_Announce&forum=EWB_General&forum=EWB_Components&forum=EWB_Server&forum=EWB_Demos&forum=EWB_Binaries&forum=EWB_Discussion&forum=EWB2_Preview&forum=EWB_Beta#653
>

Interesting. It was probably done for forms, but the JSON parser doesn't do it. Or if it is the same, it was never done. It wouldn't be hard to do, and shouldn't affect things generally. Obviously if you do "too much" in the AfterLoad like assume your world is all complete then that could be trouble, but that's how things are generally, and that's easy to solve too..

--

Matthew Jones
Tue, Apr 25 2017 10:11 AMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Matthew,

<< Here's an interesting one. I think that TPersistent should be calling AfterLoad for all objects it creates, including children. I have a complex object (TDetailItem) that is stored in a list contained by another object (TBigObject). The logical place to do the "I've finished loading" code is in the TDetailItem AfterLoad, but it is never called, because it is a child of TBigItem and it is that which gets the AfterLoad. >>

I'm not sure what you're asking here.

The TPersistent.AfterLoad method looks like this:

procedure TPersistent.Load(AReader: TReader);
begin
  BeforeLoad;
  try
     if AReader.IsArray then
        LoadArray(AReader)
     else if AReader.IsObject then
        LoadObject(AReader)
     else
        LoadProperties(AReader);
     if (Self=AReader.RootComponent) then
        AReader.ApplyFixups;
     AfterLoad;
  except
     on E: Exception do
        LoadError(E);
  end;
end;

So, as long as a given instance is a TPersistent descendant class, then AfterLoad will get called after the instance is loaded.  In other words, make TDetailItem a TPersistent descendant class, and you'll get what you want.

Tim Young
Elevate Software
www.elevatesoft.com
Tue, Apr 25 2017 11:03 AMPermanent Link

Matthew Jones

Tim Young [Elevate Software] wrote:

>  AReader.IsObject then
>          LoadObject(AReader)

This is the key. This loads an object. But it does not call AfterLoad for that object. So you are calling it for the "big parent" original object that is loading, but not for other objects contained, or stored in an array. LoadObject needs to call AfterLoad for the individual item too.

--

Matthew Jones
Thu, Apr 27 2017 10:12 AMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Matthew,

<< This is the key. This loads an object. But it does not call AfterLoad for that object.>>

Yes, because it *isn't responsible* for calling AfterLoad for that object.  EWB effectively punts on how objects are loaded, and doesn't assume that you always want to load objects in a certain fashion.  Why ? Because it doesn't know how to create the objects in the first place. In the case of controls, it knows how to create each child control because each incoming child control has a special ClassName property that is used by EWB to lookup the class name and create an instance of the class.

IOW, if you want your class to load its child classes as TPersistent classes, then you need to override LoadProperty and handle them as such.  Check out the TControl.LoadProperty method in the WebCtrls unit for information on how to do this.

Tim Young
Elevate Software
www.elevatesoft.com
Thu, Apr 27 2017 12:35 PMPermanent Link

Matthew Jones

Tim Young [Elevate Software] wrote:

> then you need to override LoadProperty and handle them as such

I shall have to look at my code again, as I do indeed do a lot of such handling. Obviously I need to work out where to fit the relevant call into things.

--

Matthew Jones
Image