The only(!) approach that works for both JSON and OData Model is to go via the binding:
oTable.getBinding("items").getLength()
If you have a JSON Model, this will return the same as as oModel.getProperty("/data/items").length (assuming that's the binding path for your items aggregation). If you have an OData Model, it will return the number if records that are potentially available. Remember that the OData Model only manages a chunk of the actual data on the client and loads any other data on demand. So say there are 300 Sales Orders in the Backend and the client currently only has the first 100 records, the above approach will still return 300.
On a side note: You'll most likely (and should) work with asynchronous requests. That means that the data might not necessarily be there in onAfterRendering. To me, it seems like you want to trigger an action when the data has been received by the client. For that, look into the dataChange or dataReceived event of the Binding class. You can attach to these events also via oTable.getBinding("items").
- Max