Are there best practices for user interface for editing complex object structures in TYPO3/Extbase (like IRRE frontend editing)?
Let's say I have an object A with 1:n-relations to child objects of type B and C.
Ideally I would like to have a page that makes it possible to edit an A (including adding/modifying/deleting B and C instances without persisting on the fly).
I currently have separate pages (for editing A's, B's and C's) and use the corresponding controller's CRUD actions. Is it possible to edit A's including their children while still using the Extbase object model/concept?
Related
I have recently added some fields for auditing purposes to existing models in an MVC 4/ Entity project. I don't need these fields to be displayed on the edit page. However, they are required fields on the model.
As it stands, the edit page still works, but on the controller side, the ModelState.IsValid check fails because the required fields that are actually set on the item are not output to the view and therefore not re-submitted when the edit page is submitted.
Is there an easy, built in way to rectify this, or if not, which of the following is best practice for this scenario? Are there more options?
1) Set up hidden fields on the view to hold the information (Not a fan of this option, passes data around too much)
2) in the controller, on submit, first load the model by ID, then set each individual parameter based on the fields present on the view (Seems like extra unnecessary work)
3) Create a constructor for the model that takes itself as a parameter and pulls any non-default values and returns a new object. Basically a merge. (Best I think, still a lot of extra work)
4) ???
Best practice is to not use your domain model inside the views. Create a view model class that contains only the id and the fields you want in the view. Pass this model to your view. Change the parameter type of the form submit action to match your new view model. This will then pass the model validation without using hidden fields. In your action method, you can then retrieve the object from the database using the id property of the view model class and update fields as required.
Hope that makes sense.
I prefer to do the 2nd option as long as I can get the existing object with a single query or db call. This lets me to keep my view clean(no hidden fields for all those other properties) and use the existing update method which updates the domain model.
Look into your code. If the update method is making updates in lot of other places(many other tables) which is really not needed, then you could possibly write a short version of the update method which updates only the relevant parts ( ex: UpdateContactDetails).
Consider the following scenario
We have a simple database that involves two entities: user and category.
For our hypothesis let's say that a user can have only a type of category and a category can be associated with n users.
Now, consider a web page where a user - say ROLE_ADMINISTRATOR - could edit user table and associate them to a different one category.
As far I know (and I'm still new to symfony in general) if I use Doctrine and symfony2 in tandem, with - let's say - annotation method, i'll have two entity (php classes).
Embedded form
I will create a form that will show the user and, for show - and persist, of course! - also his category I "choose" to follow the "embedded form" strategy.
Having said that the entity has been created, i'll have to create a form for category (suppose that into formBuilder I'll add only id attribute of the category).
After that I have to add to formBuilder of UserType class the previous form and, with "some kind of magic" the form will render (after the appropriate operations) as magic and just as magically, when i'll post it (and bind, and so on) back all the informations will be persists onto database
Data Transformers
A.K.A. trasnform an input of a form into an object and vice versa.
In that way I'll have to define a - let's say - CategorySelectorType that into his builder, will add a Class (service ?) that will do those transformations.
Now we define the data transformer itself that will implement the DataTransofmerInterface (with his method and so on...)
The next step will be register that entity into services and add into UserType the form that will use this service.
So I don't understand any "strong" difference between those two metodology but "reusability" of the service. Somebody can offer me a different point of view and explain me the differences, if any?
A data transformer does not replace a embedded form, it rather enhances forms and wraps data transformation nicely.
The first sentence on the cookbook page about Data Transformers sums it up nicely:
You'll often find the need to transform the data the user entered in a
form into something else for use in your program.
In your example above, you could add a drop-down list of categories so the admin can select one for the given user. This would be done using a embedded form. As the category field is the id of an existing category, there is no need to transform the data.
For some reason you now want the admin to be able to enter a free text of the category. Now you need to do some tranformation of the text into the object in question. Maybe you want him to be able to either add a new or select a current category with this text field. Both is possible by using a data transformer which takes the text and searches for the category. Depending on your needs, not existing categories can be created and returned.
Another use case is when a user enters data which needs to be modified in some way before storing them. Let's say the user enters a street, house number and city but you want to store the coordinates instead.
In both cases it doesn't matter if you embed the form into another!
Could you do that in your controller? Of course. Is it a good idea to do such things in the controller? Probably not, as you have a hard time testing (while doing it in the transformer let you unit test the transformation nicely) or reusing it.
UPDATE
Of course it is possible to place the transformation code someplace else. The user object itself is not a good place, as the model should not know about the entity manager, which is needed to do the transformation.
The user type would be possible, but this means that it gets tied to the entity manager.
It all adds up to the very powerfull concept of Separation of concerns, which states that one class should only do one thing to make it maintainable, resuable, testable and so on. If you follow this concept, than it should be clear that data transformation is a thing on its own and should be threated as such. If you don't care, you may not need the transformation functionality.
A "Lookup" in this example is an IList<string> of state abbreviations. Generally, your Domain Model POCOs won't include these options. ViewModels usually take this responsibility referencing both the original Domain Model as well as the Lookup object, but what happens when the Domain Models are nested and you are using MVC templates (which won't have access to the original Model's root properties?
Is there a way to include the Lookups in one object and the Model in a different object for the template? Is it permissible to assemble on-the-fly a ViewModel specific to that Template within the View (which would have to include any nested data from there)? I would think static methods to pull down Lookup values is bad.
Any ideas?
Notes (to my knowledge):
A Domain Model POCO from a repository doesn't change in structure. If you need a single Model to have both the Customer object and the DDL options for US State for example, you normally have a ViewModel that references the Customer object and the Customer Lookup lists.
However, when you have a nested Domain Model (aggregate root), the nested objects have no where to put the Lookup Lists, and the MVC templates cannot access the root level View Model (their view model is the partial Model).
Edit:
Is there some way to put the DDL lists in the root level of the ViewModel, then when you get to the Customer object, construct a new ViewModel that references the root level DDL lists and the current Customer object to send to the template? This would eliminate duplicate data in the Model as well as use a single Model for all the Views. The only bad would be Controller like data assembly code in your view (which is just as bad).
A couple of suggestions. First, use separate view models for your views -- don't directly use your domain models. These view models can, and should, carry the extra data needed by the view. Second, you can use the overloads on DisplayFor/EditorFor to pass additional view data to the template. That way your template can be specific to a particular domain model and yet have access to the additional data in the view model.
For static, unchanging lists like state abbreviations, you could use Application state or Cache entry. These types of lists could be loaded in Application_Start from a database.
I'm completely new to M-V-VM and very new to Silverlight, just reading about it for the first time today. As a sample, I am creating a model containing a list of items. My (Silverlight 4) View contains a listbox and my ViewModel will look to the model to retrieve the collection that the listbox will bind to.
My question is this. I think it would be good to use an ObservableCollection to hold the items that the listbox binds to. This would be an ObseravleCollection in the ViewModel. Should I also use this type of collection in the model, or should I use another collection type and do smoe conversion between model and viewmodel?
There are 3 basic scenarios (in order of increasing complexity):
model simply provides an access to a backend services and does no caching of data flowing through it at all
model exposes a collection of items, vms don't have their own collections, and then views are simply bound to collection in model object
model exposes a data source, vms have their own collection that serve as window into this data source, and views are bound to collections in vms.
In first case you'd use List to simply pass a requested data to vms, in other cases you'd use ObservableCollection so that either views will be properly updated via binding (case #2) or vms can properly update its own collections (case #3)
the usual way of doing this is to use IList/List or something similar in the model and then do a conversion in the ViewModel. So in the model you will have something like IList and in the ViewModel you convert it to ObservableCollection (usually in the ViewModel's constructor).
Cheers, Alex
I would like to experimentally apply an aspect of encapsulation that I read about once, where an entity object includes domains for its attributes, e.g. for its CostCentre property, it contains the list of valid cost centres. This way, when I open an edit form for an Extension, I only need pass the form one Extension object, where I normally access a CostCentre object when initialising the form.
This also applies where I have a list of Extensions bound to a grid (telerik RadGrid), and I handle an edit command on the grid. I want to create an edit form and pass it an Extension object, where now I pass the edit form an ExtensionID and create my object in the form.
What I'm actually asking here is for pointers to guidance on doing this this way, or the 'proper' way of achieving something similar to what I have described here.
It would depend on your data source. If you are retrieving the list of Cost Centers from a database, that would be one approach. If it's a short list of predetermined values (like Yes/No/Maybe So) then property attributes might do the trick. If it needs to be more configurable per-environment, then IoC or the Provider pattern would be the best choice.
I think your problem is similar to a custom ad-hoc search page we did on a previous project. We decorated our entity classes and properties with attributes that contained some predetermined 'pointers' to the lookup value methods, and their relationships. Then we created a single custom UI control (like your edit page described in your post) which used these attributes to generate the drop down and auto-completion text box lists by dynamically generating a LINQ expression, then executing it at run-time based on whatever the user was doing.
This was accomplished with basically three moving parts: A) the attributes on the data access objects B) the 'attribute facade' methods at the middle-tier compiling and generation dynamic LINQ expressions and C) the custom UI control that called our middle-tier service methods.
Sometimes plans like these backfire, but in our case it worked great. Decorating our objects with attributes, then creating a single path of logic gave us just enough power to do what we needed to do while minimizing the amount of code required, and completely eliminated any boilerplate. However, this approach was not very configurable. By compiling these attributes into the code, we tightly coupled our application to the datasource. On this particular project it wasn't a big deal because it was a clients internal system and it fit the project timeline. However, on a "real product" implementing the logic with the Provider pattern or using something like the Castle Projects IoC would have allowed us the same power with a great deal more configurability. The downside of this is there is more to manage, and more that can go wrong with deployments, etc.