This is a small improvement, but I think it is worth mentioning since it may interest more than one.
For the purists of the view-controller model, the use of the classic Xailer Data-controls is not appropriate, since all the editing process also occurs in the view, when it should be done in the controller. The most convenient way to avoid this problem is to use objects of type TMemDataset that return a memory recordset that is completely unbound from the table from which it came. But it has the disadvantage that the insert and edit operations are more complex since it requires the construction of the insert and update SQL strings manually. Let’s see how Xailer 8.1 solves this problem with a small example:
CLASS TControlador oDataSource METHOD RSClientes( oRs ) METHOD ClientesUpdate( oRs, nId ) END CLASS METHOD RsClientes( oRS as CLASS TMemdataset ) CLASS TControlador WITH OBJECT ::oDatasource IF oRs != NIL :QueryMemDataset("SELECT * FROM CLIENTES", "", oRs ) ELSE oRs := :QueryMemDataset("SELECT * FROM CLIENTES") ENDIF END WITH RETURN oRs METHOD ClientesUpdate( oRS, nId ) CLASS TControlador WITH OBJECT ::oDatasource TRY :BeginTrans() :Execute(oRs:SqlUpdate("idCliente", nId )) // Aquí se pueden hacer más operaciones de forma clara :CommitTrans() CATCH :RollbackTrans() END END WITH RETURN NIL
The update operation is performed in the controller with the additional advantage that we can include any operation within the same transaction. For this, the new method SqlUpdate( aWhereCols, aWhereValues) is used, which creates the SQL statement with only the columns that have changed their value. As you can imagine, there is also a new method called SqlInsert().
Another of the peculiarities that this code has in its RsClientes() method that I think is very interesting is that the TMemDataset object is passed as a parameter, instead of being created in the method itself and returned as a return value, which could be the first approach that any programmer would make. This technique has a great advantage, which consists of being able to incorporate an empty TMemDataset into the form itself and even link it to a browse in which we have completely defined the columns and everything visually. If our method were responsible for creating the TMemdatset and returned it as a return value to then assign it to the browse with oBrowse:oDataset := oController:RsClientes(…) we would observe how all our browse columns would disappear since a new dataset and that causes a reset of the entire control. On the contrary, if we pass the recordset as a parameter, everything is perfectly maintained.
And that’s all, for now. Soon, more news.
All the best