I am trying to follow the Wizard pattern in Forms sample provided with Play (https://github.com/playframework/Play20/blob/master/samples/java/forms/app/views/wizard/form1.scala.html).
This approach looks okay when the number of fields are static. But, how do I deal with this when the fields are dynamic. e.g. if there are going to be multiple profiles that a user can create in step2, how do I represent it on this page?
Also, does it mean that every page of my wizard will have to know about all the controls on rest of the pages, and make those hidden? There must be a better approach to solve this problem. Can you pls help?
I had similar problem while working with wizards. I solved it by decoupling my DB models from UI models. e.g. at DB level, I have one model that represents a whole car. At UI layer, I created multiple models that represent parts of the car e.g. wheels, seats, doors etc.
In the UI wizard, I use the UI models. So, at any given step my wizard step only needs to know about the parts that it operates on. I can apply the validation constraints such as #required etc. on these models. If form validation on part succeeds, I would update the DB model with that information. HTH.
Related
I have an ASP.NET Blazor server-side project, using EF Core. One of the pages is getting quite large. Apart from any other reasons for keeping code files a reasonable size, the large size causes significant delays when recompiling.
I would like to split it down into smaller components, but the problem is that the whole page represents a fairly large object graph, parts of which are used in multiple places on the page.
Imagine a page that shows details for a company. The company has many employees, each of whom can claim expenses, which are added to the company's transactions list. The company itself has income and expense, so that adds more transactions. Other parts of the company object graph might also have associated expenses. This is a very simplified (and fictitious) sample of the idea. The page has various sections, such as one for employee details, which shows their transactions, as well as an overall transaction list.
At various places, you can add transactions, which get associated with the employee (or whatever), and are shown on both that transaction list and the main one. All of this is done with individual forms for each action, it's not one huge form for the whole object graph.
If I were to split the component down, I would be faced with one of the following choices (unless someone can suggest another)...
Have each smaller component inject its own DbContext and handle its own data access. This is fine in theory, but would cause concurrency problems as it would mean that different components were saving changes to the same entities. It would also require a lot of events to inform the parent component that data had changed in the subcomponents, which would end up very messy.
Have each smaller component have parameters for the bits of the object graph they handle. This avoids any concurrency issues, as only the parent component would be doing any data access. I'm not sure if it would avoid the need for events, as it depends on how well Blazor would notice if a part of the graph passed to a subcomponent changed.
Pass the DbContext in to each smaller component as a parameter. Again, this avoids any concurrency issues, but really feels like the wrong way to do it.
Anyone able to guide me as to the best way to split this up?
Thanks
If you have lots of sub-components accessing the data in the Form [your top level component - some sort of dashboard?] then you probably have quite a bit of plumbing to try and keep everything in sync, or lots of rendering going on if you are cascading objects. How often are you calling StateHasChanged?
Without some code I can only answer in very generic terms.
Your first step is to separate out your data and data management from your components and form. Move the data and the database into a DI service. The scope depends on what you're doing: Transient or Scoped. You can then use normal events to signal updates to components that need to render if something changes. There's an answer here that shows how to do this - https://stackoverflow.com/a/69562295/13065781.
[Opinionated] You also need to understand that by building a complex object (your DataGraph) and then letting EF manage it's state, [in Clean Design terms] you're building core application logic (the relationships between your basic data objects) into your infrastructure layer. The advantage is it makes things easy, and saves a lot of coding. The disadvantages come to light over time.
I'm working upon a small-scale enterprise database application. It works with such business objects as Vendors, Device types, Devices, Suppliers, Invoices, Departments, Employees etc., so I need to let users view and edit data from all these tables.
My first approach was to create a pair of forms for each type of business object:
a table to view and select an object
an editing form for this type of object
But now I find it hard to maintain all these forms, because e.g. if I want to change the look of all view forms, of course I have to edit each one of them.
So I want to replace all my view forms with a single one "template" form and to call it with some kind of parameters. The problem is, I don't know the right approach to perform it. Maybe there could be some example in some book or somewhere else?
I think the best way is by using Visual Form Inheritance .
Actually we use this kind of programming a lot, it keeps maintenance pretty simple. Stick your base functionality in the parent form, and specific behaviour in the child forms.
As I have a complex domain model (DDD) where I need to create a few hundred forms in the user interface, I'm looking for a generator, preferably embedding the apple layout rules, and data binding. This is crucial to get a uniform application appearance.
I would prefer the generating to be of run-time instances (introspection), not static source code.
I do not want to build from a data model, as that doesn't have enough information to create something useable. I have information on grouping, validation, roles and rights, navigation, filtering, actions, workflow so I should be able to do much better layouts.
Even better would be the ability to also generate forms for the iPhone/iPad, using the default navigation.
[Results]
Sensible TableViews looks like the right kind of solution for iPhone. The descriptions are not yet sophisticated enough but provide a good starting point.
Interface Builder will do this for Core Data models if you option-drag parts of (or all of) your data model from the Data Modeler into a window or view in Interface Builder.
When you drop the managed object(s) you dragged, you're given an option to create a Single Item View, a Master/Detail View (with search and detail fields and add/remove buttons), or a Collection View (with box + search field).
I don't know of any third-party solutions to do this from "just any model." It'd be a great tool, but would likely require using an object model to define the entities (like Core Data's Managed Object Model).
Sensible Tableviews Might be able to help you. I haven't used them myself but it looks solid. It also supports generating forms from core data entities.
Maybe Echasoft Reports would work for your problem? (Plugin for Interface Builder that gives you easier reporting capabilities). I saw this demoed at NSConference, and it looks pretty awesome. Commercial, yes, but for 100+ forms it might be worth the money...
I wonder in which cases it would be good to make an NSManagedObjectModel completely programmatically, with NSEntityDescription instances and all this stuff.
I'm that kind of person who prefers to code programmatically, rejecting Interface Builder. But when it comes to Core Data, I have a hard time figuring out why I should kill my time NOT using the nice Xcode Data Modeler tool.
And since data models are stuck to a given state (except when you want to do some ugly migration operations where thinks probably go wrong and users get mad, really mad), I see no big sense in a data model that's made programmatically for the purpose of changing it all the time.
Did I miss something?
I dont think you missed anything. The only reason I can see to create your model programatically would be if the objects you are modeling are themselves dynamic: you could for instance build a coredata entity (or graph of entities) in response to a web service which changed over time, or was selected by the user. However, I think if you had that or a similar use case, you wouldn't need to write this question (and you'd probably solve it a different way anyway)
So, if your application is dealing with resources that are dynamic, as #Andiih mentioned, then this programatic is the only way to do it. I don't know what my core data entities are until runtime, I don't know what the attributes are, or what the data looks like. So, I ask the server to give me the kinds of resources I should support and what their attributes look like. I build the model, the entities, the properties, the relationships - at runtime. I still want to use Core Data because I'm dealing with a lot of data and I need the benefit of efficient memory management with NSFetchedResultsController, etc. I can only do this programmatically.
The trouble is how to handle migration to try and preserve as much of the persistent store as possible, to reduce the size of the networked data payload after the model changes. Right now I blast the whole model and the persistent store if there's a conflict. I haven't yet figured out a way to create an .xcdatamodel from a programmatically generated model, thus I can't yet create a version mapping to do the migration.
Everything is a trade off. Basically, I think IB and the visual Core Data modeler are the right tool if you're building a simple application. You'll need to make the determination when your application becomes large/complex enough that you prefer to have direct control over all aspects of the code.
Regarding Interface Builder, if you have an application with a variety of complex interactions between view controllers, and multiple custom controls, I find code more appropriate.
For Core Data, the question is pretty much the same. Does your project have a defined scope? Can you foresee everything in that scope being done within the visual modeler? If so, it's probably fine. For other projects, where you may be asked to add features on an ongoing basis, perhaps it's better to spend a little more time writing it out so you have more flexibility later.
One other thing to consider, that doesn't get mentioned much, is it's MUCH harder to ask for help with IB or any hybrid visual design/code system. When something does go wrong, or you need help, it's way easier to post your code, than try to explain what's going on in a visual modeler.
In general, there's no reason to build the managed object model in code. There's nothing you can do in code that can't be done in the model editor. There are some fancy tricks you can do in code, however, to work with multiple models. For example, you can merge two models, establishing cross-model relationships between entities in those models at load time (see Cross-model relationships in NSManagedObjectModel from merged models?).
Regarding whether it's a good idea to code or use the graphical editor, I think the balance tips heavily towards the graphical editor in this case. Being able to verify the model by visual inspection instead of (rather convoluted) code is a win. The model can still be verified by unit test, if you desire.
I have one use case that might be valid, what if you load some data from the internet whether it is XML from an RSS Feed or WSDL response, then flatten those responses into a tabular from generating an in memory data table and finally mash it all up into a single coherent data model, then you can create the entities for those in memory data tables and create master/detail relationships. That's one case I think Core Data data model generated programmatically could become handy and a powerful feature.
I've changed models programmatically in unit tests. For example, I wrote a class that is designed to work with Core Data models that have a particular protocol attached. Instead of testing against a random implementation, I mutated the default model by adding one just in the unit tests programmatically, and tested against that test-only model.
I have Lotus Notes application, deployed only as modifications (new forms, views, and adding a button to one of the "standard" views) in the main mail template (R7).
All these "new" forms and views are inherited in turn from my main application template.
Now, for one of these forms to function properly, it have to have a field, which is different from customer (not end user, but organization) to customer.
I do not want to break the inheritance from our template, so we can update the application easily by just sending a new template. So, I can't ask the client admin just to break the inheritance for this particular form, as it will stop all updates (or they have to be done manually).
So, let's say I have MainAppForm, which has a calculated field ClientCustomData. I'd like to have another form, which only has only one "default" field ClientCustomData. I can break the inheritance for this second form, as it has no really design elements which may change, and then the client can modify this default value to whatever they need w/o fearing that it'll be overwritten.
The question is - how from MainAppForm I can read the value from the other form?
Or - is there a way to store 2 data elements only in a mail template (I dunno, shared file, or something), so it becomes available to each user, and MainAppForm can get them, w/o a need to remove the inheritance dependency of MainAppForm from our template.
I can envision even a class library with just to functions to return this (I don't know why this approach smells to me).
Any best practices or advices?
I'm not sure if I have understood your querstion correctly, but it sounds like you want to have a small part of a larger form configurable per client. If this is the case, I think computed subforms could do the trick.
Consider the following scenario: Your application ships with the subform ClientCustomData that contains just sensible defaults for the client settings. The form MainAppForm includes this as a computed subform. It is then possible for the local admin to disable inheritance on the subform and changing the custom data without affecting inheritance on MainAppForm.
The obvious drawback is that you cannot update the ClientCustomData subform automatically once inheritance is disabled; Keep this subform as small as possible. If you find that you need more client-custom values, you can always add another subform in the same manner.
First a clarification: In Lotus Notes, you don't have forms reading from other forms. Forms are just UI objects. However, you do have back-end and front-end documents that get created with the help of Forms.
When you create a new document based on a form (for instance, a new email), you are creating a front-end document that hasn't been saved yet. That document can access other parts of itself or it can access any back-end document that has been saved.
If I'm following you correctly, you need some bit of data that is different per client/customer to be brought into documents based on MainAppForm. There are a few ways to do that. My suggestion is to use Database Profiles, which are special documents that can easily be accessed from anywhere in your database via Notes Formula language or LotusScript. Granted, you can't push data within those documents out via a template, but if you use a database profile to store your database settings your client admin can set options once and they won't get altered when the template changes.
Have a look at the #SetProfileField and #GetProfileField functions.
To answer my own question (still I do not know if I'm right in terms of Notes way of thinking, but looks promising):
I found the "Shared fields". So, I create 2 such a fields with a computed values (the ones I want to pass on), and make my MainAppForm use them. Upon installation, the admin will change the values and mark them to not refresh with the template.
I'd respect any pros and cons, provided from a Notes expert.
Thanks