In demonstrations of master-details scenarios, it is common for the details view to show vertically what the master view had shown horizontally. In a real application, the details view is usually required to show more information than can be contained in the master view. In the database of my Mix 09 application, there are tables for information about the presenters and the sessions at Mix 09, with a many-to-many relationship existing between the two. So far, only data from the Presenters table is being displayed. In the next couple of posts, I will look at handling data from multiple related tables. To begin with, I will assume that each Session is given by only one presenter. Afterwards, I will extend the solution to allow several presenters to give a single session.
To get the extra data now required for the details view, a request must be sent to the ADO.NET Data Service whenever a presenter is selected in the Presenters Dataview:
The use of the fetchData method is familiar from earlier posts. In this case, a single record from the Presenters table is being requested, the uri for which is obtained from the metadata of the data item that is sent as the command argument to the onCommand function. The use of the $expand attribute, however, is new. This attribute tells the Data Service to return data from other database tables related to the table containing the record being requested. The Presenters table, you might recall, is related to the Links table, which in turn is related to the Sessions table. By setting the $expand attribute to “Links/Sessions,” the Data Service is told to return the relevant data from the Links table and the Sessions table. The result of this request is handled by the ExpandedFetchSucceeded function:
Most of this code was previously contained in the onCommand function; but now, instead of directly setting the data of the PresenterDetails Dataview with its set_data method, I have created a binding between the PresenterDetails Dataview and the selected item in PresenterDataView. This selected item, it should be noted, is automatically updated with the extra data just received from the Data Service. By setting mode to Sys.BindingMode.twoWay, the data in one bound object is automatically made to reflect changes to the data of the other.
The selected data now has as one of its properties an array of Links, each of which has as one of its properties a Session. To display the Session data, I used a nested Dataview:
I added an extra row to my details table, and put another table inside that row. This was the quickest (if not the best) method. The attributes needed to create a Dataview were described in a previous post. It is important to notice here that the data property of this Dataview is set to Links, which, as just mentioned, is an array property of the object to which the parent Dataview is bound. The child Dataview generates, in this case, a table row for each item in the Links array. Each row contains an input element of type text, the value attribute of which is bound to the Name property of the session object, which is just a property of the Link object. Nothing more is required to make the Dataview display the names of the sessions that a presenter is giving. Even more surprising, changes to the information about the presenter and his sessions can be saved to the database simply by calling the saveChanges method of the datacontext:
The use of a binding has therefore made saving updates even easier than before. The only additions necessary are the RemoveBinding function, which is called whenever the popup is closed, and the call to the clearChanges method of the datacontext, which ensures that cancelled changes are not submitted to the database.