VLWeb Deep Linking Sample

This Q&A forum allows users to post and respond to "How Do I Do ....." questions. Please do not use to report (suspected) errors - you must use your regional help desk for this. The information contained in this forum has not been validated by LANSA and, as such, LANSA cannot guarantee the accuracy of the information.
Post Reply
jyoung
Posts: 694
Joined: Thu Jan 21, 2016 6:43 am
Location: Oklahoma City, OK USA

VLWeb Deep Linking Sample

Post by jyoung »

Looking through the Deep Linking Sample trying to find a way to improve my own "View Navigation" mechanisms.

It looks like the sample demonstrates the same issues I run into. Triggering a view change on a user action and triggering a view change on the URL change event causes the view to be "activated" twice.

The problem is here

Code: Select all

evtroutine handling(#sys_web.URLChanged)

* Browser URL has changed, so activate the employee specified
if (#sys_web.URLParameters<Employee> *IsNot *null)

#Com_owner.Activate( #sys_web.URLParameters<Employee>.Value )

else

#Com_owner.Activate( "" )

endif

endroutine

evtroutine handling(#List.ItemClick)

#Com_owner.Activate( #xEmployeeIdentification )

* User has clicked an item, so add it to the history
#Sys_Web.History.Add( ("Employee=&1").Substitute( #xEmployeeIdentification ) )

endroutine
In the List.ItemClick event the view gets activated AND it is added to the history. When the history is added, the URLChanged event fires, activating the view a second time.

You can see this in the chrome dev tools by monitoring the network traffic.
Capture.PNG
Capture.PNG (19.68 KiB) Viewed 10778 times
On the initial load, everything is fine. But select an employee and two requests are triggered because the activate is caused twice.

Code: Select all

mthroutine name(Activate) help('Update the page to show a specific employee number') access(*PRIVATE)
define_map for(*INPUT) class(#xEmployeeIdentification) name(#EmployeeNumber)

* If an employee number is supplied...
if (#EmployeeNumber <> "")

* Position to the right one in the list
#Com_owner.PositionTo( #EmployeeNumber )

* Update the detailer to show the employee
#EmployeeDetails.ShowEmployee( #xEmployeeIdentification )

#EmployeeDetails.Opacity := 100
#EmployeeDetails.Enabled := true

endif

endroutine
The only way I have been able to solve this is to keep track of what "view" I am currently displaying. Then in the URL Changed event, If the URL view does not match my current view, I allow the view from the URL, BUT DO NOT ADD IT BACK TO THE HISTORY.

Curious how other folks are solving this problem.

It would be nice to have a built in mechanism to handle issues like this. Much like a "router" in Angular, React or Ember. While VLWeb works great without it, it breaks the User's concept of how a web application should work. Meaning they can hit the back button and lose all state and navigation of where they were in the app.
GregSippel
Posts: 25
Joined: Thu May 19, 2016 11:34 am

Re: VLWeb Deep Linking Sample

Post by GregSippel »

Joe,

There are 2 big lessons that I learned with "Deep Linking" or as I term it URL Navigation.

Lesson 1) Don't start adding to history until you reach the view that is essentially the home or root view. By this I mean if you have a login view, this is shown first to the user but once they have signed you normally display an initial screen. From this initial screen, you start adding to the history so the user can go to other views or detailed information in a view. This way when the user does use the browser back, they will be routed back to the initial view. If they go further with the back key they then will leave the application. The other effect of doing this is if the user accesses the page on mobile after saving it to the home screen, once the browser runs out of history the browser will close the page. Thus you get the same effect as a normal app.

Lesson 2) To make your life easier, the displaying of views should be done via the URL changed event. The normal logic you use to show a new view is we listen to you the event that will trigger the navigation, then we ask the application to change the view. As you discovered this works well if you aren't concerned about allowing the user to navigation via the forward and back keys. To handle the browser navigation keys your logic needs to change just a bit, we now have to do the view change in two parts.

1) Ask the application for a new view. At this point, your application can respond to the event that triggers the new view by using the #sys_web.history.add to change the URL to reflect what you want to do. At this point the #sys_web.URL changed is fired.

2) Response to the URL being changed and then display the panel. At this step your logic in the #sys_sweb.URLChanged can the figure out from the URL what is being asked and then cause (via methods and/or events) the application display the requested view. Then in hierarchical navigation situations (such as drilling down on a list), your code can ask for the browser to step 1 back in history via the #sys_web.history.back

So by following this pattern, you are allowing the application navigation to be driven by the URL. Whether you are programmatically doing it, or the user is doing it via browser navigation controls the same result is achieved because the same pattern is being followed.

I have followed this pattern for several VL applications now and it works well. I put all the URL logic into a reusable part either as part of an application controller or by itself but making it globally scoped. So to change a page I 1) Call method like #app.navigate.to('view2','ID123'), this adds to history with a URL like https://myhost/lansa/partition/myapp.ht ... &id=iID123. Then 2) #sys_web.urlchanged is fired, my logic can see the app what view2 and to display the details for ID123. So I call a method in my #app from the URL managing part, such as #app.displayview(''view2','ID123'). This changes the view, normally I have my views in a keyed collection so to display one I go #view<>.visible := false and then #views<#newview).visible := true. I then signal that ID123 is wanted and that takes care of the display logic.

Hope this helps

Cheers
Greg
jyoung
Posts: 694
Joined: Thu Jan 21, 2016 6:43 am
Location: Oklahoma City, OK USA

Re: VLWeb Deep Linking Sample

Post by jyoung »

Hi Greg,

Very well put. Thanks.

Your "lesson 2" was what I have been struggling with and have been approaching the same conclusion has you have. As you state, you have to do it in two parts. I have been doing it one, like the sample, but to work effectively it requires some state management, which as you state as well, makes life difficult. You mention navigate and it made think of the two parts being navigation and presentation. Whereas to "navigate" you manipulate the URL and to "present" you listen for those URL changes and manage your transitions accordingly.

Thanks again!

Now I am going to refactor my apps. lol.
Post Reply