I'm trying to do a record-based in-grid editing with my own QAbstractTableModel-descendant class and a QTableView. When the editing is finished, the model recieves a signal to it's submit() or revert() slots. But there are no parameters, so the model does not know which record it needs to submit to (refresh from) a datastore. I've tried to setup my own change-tracking by catching model.setData()/removeRows()/insertRows() , but it's kind of a mess. Is there a right way to do it?
Per the docs on QAbstractTableModel:
Subclassing
When subclassing QAbstractTableModel, you must implement rowCount(),
columnCount(), and data(). Default implementations of the index() and
parent() functions are provided by QAbstractTableModel. Well behaved
models will also implement headerData().
Editable models need to implement setData(), and implement flags() to
return a value containing Qt.ItemIsEditable.
So the fact that you are re-implementing setData, removeRows, and insertRows is appropriate. The other subclasses of this class also use their own internal caching to track what is being changed, so that it can commit it to the data source when needed. If your approach is a mess so far, then you probably just need to improve what you are doing, as the path is correct.
setData is where you can track what is being changed in an internal data structure. So for instance, if your model were a basic dictionary internally, and would submit to a web-based REST service, you would manage changes to the data in your internal dict. When submit is called, you would use that internal cache to make the necessary REST call to send out the data and sync it.
Related
I'm migrating a legacy PHP project (pre-OO) to Symfony2. On every request I have to:
compute some dynamic data (depending on the current date and/or some request parameter)
use that data (multiple times!) in the rendered response.
A naive approach would be:
At the start of every controller method, call some global helper function to compute the data.
At the end of every controller method, pass the data as a parameter to the twig template.
Sounds tedious. Maybe it would be better to:
Create a subscriber for request events that computes the data when a request comes in and provides access to it via getter methods.
Define that subscriber/service as a global twig variable in config.yml.
In twig templates, call the getter methods on that service as needed.
Is that viable?
In particular, are the twig variable/service and the subscriber always identical? Or could the service be a newly created instance?
Is this some sort of misuse? Or is there an officially recommended way for such a use case?
EDIT The data is not only needed in every twig template but in some controllers, too.
Calling a specific method in every Controller-Action would really be a bad solution. Your solution to use a subscriber isn't perfect either.
Without knowing your use-case in detail it´s hard to find a suitable way.
Maybe one approach would be to write a Twig-Extension and injecting a Service into this Extension. The Service would get the Request-Stack via Dependency-Injection and compute the relevant Data. You could then access this data "on demand" through the Twig-Extension during the rendering.
Another approach could be using sub-requests during the rendering (Symfony: How to handle common request scope data)
Maybe these tips already helped you a bit. Otherwise let me know more details, where / how you need the data during the rendering.
I am working towards replacing an existing "heavy" commercial ORM with ServiceStack's ORMLite. In the heavy ORM, we have the ability to hook an "OnSaving" or "BeforeSaving" method to perform a validation prior to saving to the database. These methods are wired into the MyObject.Save() and occur automatically so that no upstream projects forget to call a validation method.
We currently rely on this mechanism to perform validations, address a few performance denormalizations, and assure data integrity. It's a great way to consolidate the validation into the model. (We can hopefully avoid the arguments about using a repository pattern here.)
I have searched and reviewed several ORMLite examples without finding a way to do this. Can anyone provide some clues?
As far as I know none micro orms don't support events, so you have to do it manually. I don't know your code but I will try to describe what you can do:
1. Add interface IValidation with method Validate() which return collection of i.e validation results
2. Add implementation of IValidation to each object which has OnSaving method.
3. Create generic repository pattern for you micro orm with method Save
4. In method save check if the saving object implement IValidation interface if yes, then invoke Validate() method and if collection is not empty then notify user in any way you want.
I am currently working on several flex projects, that have gone in a relative short amount of time from prototype to almost quite large applications.
Time has come for some refactoring to be done, so obviously the mvc principle came into mind.
For reasons out my control a framework(i.e. robotlegs etc.) is not an option.
Here comes the question...what general guidelines should I take into consideration when designing the architecture?
Also...say for example that I have the following: View, Ctrl, Model.
From View:
var ctrlInstance:Ctrl= new Ctrl();
ctrl.performControllerMethod();
In Controller
public function performControllerMethod():void{
//dome some sort of processing and store the result in the model.
Model.instance.result = method_scope_result;
}
and based on the stored values update the view.
As far as storing values in the model, that will be later used dynamically in the application, via time filtering or other operation, everything is clear, but in cases where data just needs to go in(say a tree that gets populated once at loading time), is this really necessary to use the view->controller->model->view update scheme, or can I just make the controller implement IEventDispatcher and dispatch some custom events, that hold necessary data, after the controller operation finished.
Ex:
View:
var ctrlInstance:Ctrl= new Ctrl();
ctrl.addEventListener(CustomEv.HAPPY_END, onHappyEnd);
ctrl.addEventListener(CustomEv.SAD_END, onSadEnd);
ctrl.performControllerMethod();
Controller
public function performControllerMethod():void{
(processOk) ? dispatchEvent(new CustomEv(CustomEv.HAPPY_END, theData)) : dispatchEvent(new CustomEv(CustomEv.SAD_END));
}
When one of the event handlers kicks into action do a cleanup of the event listeners(via event.currentTarget).
As I realize that this might not be a question, but rather a discussion, I would love to get your opinions.
Thanks.
IMO, this whole question is framed in a way that misses the point of MVC, which is to avoid coupling between the model, view, and controller tiers. The View should know nothing of any other tier, because as soon as it starts having references to other parts of the architecture, you can't reuse it.
Static variables that are not constant are basically just asking for trouble http://misko.hevery.com/2009/07/31/how-to-think-about-oo/. Some people believe you can mitigate this by making sure that you only access these globals by using a Controller, but as soon as all Views have a Controller, you have a situation where the static Model can be changed literally from anywhere.
If you want to use the principles of a framework without using a particular framework, check out http://www.developria.com/2010/04/combining-the-timeline-with-oo.html and http://www.developria.com/2010/05/pass-the-eventdispatcher-pleas.html . But keep in mind that established frameworks have solved most of the issues you will encounter, you're probably better off just using one.
I'm working with an application which was originally designed to make heavy use of static-variables and functions to impose singleton-style access to objects. I've been utilizing Parsley to break apart some of the coupling in this project, and I'd like to start chiseling away at the use of static functions.
I will explain the basic architecture first, and then I'll ask my questions.
Within this application exists a static utility which sends/receives HTTP requests. When a component wishes to request data via HTTP, it invokes a static function in this class:
Utility.fetchUrl(url, parameters, successHandler, errorHandler);
This function calls another static function in a tracking component which monitors how long requests take, how many are sent, etc. The invocation looks very similar in the utility class:
public static function fetchUrl( ... ):void {
Tracker.startTracking(url, new Date());
...
Tracker.stopTracking(url, new Date());
}
Any components in this application wishing to dispatch an HTTP request must do so via the web utility class. This creates quite a bit of coupling between this class and other components, and is just one example of several where such reliance on static functions exists. This causes problems when we're extending and refactoring the system: I would like to decouple this using events.
Ultimately, I'd like each component to instantiate a custom event which is dispatched to a high-level framework. From there, the framework itself would relay the event to the correct location. In other words, those components which need to perform an HTTP request would dispatch an event like this:
dispatchEvent(new WebRequestEvent(url, parameters, successHandler, errorHandler));
From there, Parsley (or another framework) would make sure the event is sent to the correct location which could handle the functionality and perform whatever is necessary. This would also allow me a stepping-stone to introducing a more compartmentalized MVC architecture, where web request results are handled by models, injected by the framework into their own respective views.
I'd like to do the same with the tracking functionality.
Are there drawbacks from using an event-based mechanism, coupled with a framework like Parsley? Is it better to stick with static functions/variables and use the singleton-style access? If so, why? Will this end up causing more trouble in the future than it's worth?
So, short answer on Events drawbacks:
Slightly more weight on the system to use the events. Listeners, bubbling, capture, etc.. all have to be managed by the system. Much less of an issue when you're outside the display hierarchy, but still more expensive than straight functions. (then again, avoid pre-optimization, so get it right, then get it fast).
"Soft" circular dependencies can occur in complicated asynchronous systems. This means you end up with a case where A triggers an event. B notices A has changed, so updates C. C triggers an event. D notices C has changed and updates A. Doesn't usually max the CPU, but is still a non-terminating loop.
Sometimes you need to have forced buffering / locking of functions. Say component A and B both trigger the same event. You might not want C to be triggered twice (e.g., fetching new data from server) so you have to make sure C is marked as "busy" or something.
From personal experience, I haven't seen any other issues with event systems. I'm using the PureMVC framework in a relatively complicated system without issue.
Good luck.
I've got a person object with a name and age property that implements INotifyPropertyChanged. I want to hook this object up to an ASP.NET form so that the 'name' and 'age' properties bind to textboxes in a way that, when changes happen in either place (in the control or in the object) the other will get updated.
Do I create an intermediary class that listens to each textbox change events and the objects change events and handle the updates between them? What's the best way to do this?
I'm unclear on how to get business objects and the UI talking to each other.
I've stressed over this exact problem a lot.
The short answer is, yes, an intermediate item.
The trick is to NOT write ANY code per control. You should be able to place a GUI control on the screen (That may or may not take code), and then bind your business logic to it through a generic binding mechanism.
I have defined the bindings through XML, through properties files, and through constant arrays--there are a million ways...
You probably have to write code per TYPE of object bound (a listbox binds differently than a text control) and you may have to write validators (but specifying the parameters to the validators and which control the validators bind to should also be done in data)
Now all that said, I'd be really surprised if some data-driven auto-binding mechanism didn't already exist, Microsoft has been into that since VB first came out (although their implementations used to be pretty inflexible, I'm sure they do a better job now).
I'm very insistent about the 0 lines of code per control because my job has typically involved configuring complex devices with dozens of pages of controls. A typical client/server system will have 7(!) lines of code PER CONTROL just to transport data from the DB, to the server, to the client, to the screen and back (this is a minimum for plain ole "dumb" code with no smart binding tricks).
0LOC/control may not be a requirement for everyone, but it's a good goal.
Comment response:
I've done most of my stuff manually in Java, so I'm not sure I can be too much help with the specifics.
Searching for C# and binding gave me this which looks promising, although it may be binding straight to a database which is too much IMO, it should bind to a business object, but the concepts should be the same.
One way to create the bindings at first is to manually instantiate binding objects... (Please excuse my Java)
TextControl textCtrl1=new TextControl("Name Goes Here");
new TextBinder(textCtrl1, personObject, nameField);
In Java, that second line gets tricky. When you are binding to a particular field, you HAVE to use reflection to find the setter and getter for that field of the personObject. In C# I think it should be easier.
Anyway, the binder should add itself as a listener to the control and the object, then forward changes back and forth.
Does that help any?
Edit2:
As you noticed, the hard part is noticing when your property is updated. Luckily, that is optional. More often than not, you don't need to update the component once the object is set (I had to deal with this a few times when I had distributed UIs that could update each other).
So, if you assume your object won't change, the "Binding" has to do the following:
get the value from the property and set it in the component.
add itself as a listener to the component.
store the property/object (if you can manipulate properties, you're set here. If not, you need to store the object and property name, and use reflection)
bail and wait for an "updated" event from your component.
When you get the update from your component:
- store the value in the property.
- You may want to set an "Updated" flag or store the original so that if you iterate through all the binding components, you can tell if any updates need to be saved/enable the "ok" button.
Your object should always be pretty much up-to-date now.
As you build a form, you may want to put all your binding controls into a collection so that you can do a few other operations...
A "Save" operation could call each binding control and tell it to copy from the control to the property, that way you don't need to use a listener.
A "Reset" operation can reset all the controls to their original value.
A "Test" operation can ask each control if it's been updated.
. etc
The neat thing about doing it this way is that every "Operation" you wish to add is pretty trivial to add, but automatically affects the entire UI.
You probably also want a little object hierarchy of controls with an abstract base "bind" class, then a specific binder for each type of control (text field, number field, date, spinner, table, pulldown)--I think that's about it.
This can be very simple, but gains complexity rapidly. Try it with a text field and see what you can do. A simple text binding object should just be like 5 lines of code if you can pass "properties" around in C#...
Okay, totally separate answer. As I told you, I'm not very up-to-date with C# technologies, but from what I've heard, LINQ may do this entire job for you.
In fact, LINQ may be made to do exactly what you are trying to do. It doesn't exist in Java, so that's why I gave you the "Manual" version in the other answer.
The comment at the bottom of this page: http://msdn.microsoft.com/en-us/library/z919e8tw.aspx alludes to a better way.