I have a large app with a structure and UI that has been designed to meet the original requirements.
I am now faced with a situation where I have to make an alternative read-only "view" of certain parts of the app for embedding in an iframe (I have no say in this, this is how it has to be).
I'll be referring to these two ways of viewing the app at the "display context".
I am struggling with visualising how to achive this, I can see two solutions both of which have distinct disadvantages:
Have lots of ng-if directives attached to template elements, the ng-if would be bound to the current display context of the app and show/hide elements depending on how it was being used. Even if these were one-time bindings, it would potentially turn the templates into an unreadable mess of nested ng-ifs everywhere
Create entirely separate templates for the two different display contexts. While much cleaner than the first option, it would mean a lot of duplication and maintaining two templates per view whereas previously it would be one.
I should add that the nature of the views is very ng-repeat heavy, a list of data containing categories, each category contains items, each item contains a multitude of data, at each level data may need to be hidden/displayed/manipulated for display depending on the display context. I have made heavy use of directives and components to break things up into logical chunks, however these directives and components are still very much geared towards the original use, rather than the newly required one.
I have also considered creating an entirely new app for this, however I'm not sure this would bring any benefits as I'd be using controllers and injecting services containing tons of stuff that would be never used, I'd also be increasing my duplication problem.
Does anyone have any feeling, suggestions on a good way forward for this as at the moment I'm feeling anything is going to be horrible.
Many thanks
Related
Long story short, let's say one app has multiple pages with:
a form
a list
pagination
each page may require (now or in the future) custom actions to be implemented
My question is, witch is the preferred Backbone way of handling this and why (please argument) ?
Define, a pagination view, a pagination collection, a search model, search view, etc, and initialize each one as a child view in all the necessary pages. This means we will have to append child view elements into the 'master' element, and handle all the communication between these in all necessary pages.
Define a pagination view (with it's own pagination collection and search model) and extending it across all the necessary pages. This does mean that we will have to make use of template partials (for forms, pagination, etc) and bypasses the need of handling communication between child views while also removes the need of appending/removing child view elements.
Please add your way of handling these cases if not found above, remember to argument.
My personal opinion would be 2. And that is because it removes a lot of hustle with communication between child views and it makes everything much more easier to read just by extending classes, instead of having to 'manually' init child views. It also gives one the option to rewrite behavior per page when needed.
I think #2 is a poor choice.
It's a very good idea to keep templates as simple as possible. They are basically just the markup that's generated for some input object. In order to get that object to the template, in MV* frameworks you have Views, that can either pass a model to the template or send some formatted data to the template (I prefer this where possible).
Partials just create markup. You'll still have to handle events, updates to the DOM and rendering inside the view. If you only use one view it will have to handle a lot of things, something associated with poor maintainability and a more bug prone codebase.
You'll either have a lot of code in the views, or you'll end up with a lot of mixins or doing a lot of inheritance - and I have no idea which is worse.
Big things are a lot harder to test and to reason about. Avoid doing big things.
I think that another big problem with the template partials approach is the fact that you cannot rely on type information (something like interfaces), on the object that ends up in the template. It's probably easy to make it work when you have a partial or two that you just created, but, in time this information will get lost, leading to a bad development experience.
You'll need to make sure views unrelated to your changes are kept updated with the partial changes you just made for a feature.
Keep in mind that software is never done. Things always change.
Instead of thinking about relationships between models you'll have another complex challenge that you need to handle: the coupling of views through partials.
The alternative is a lot better. Composing specialized views is a good approach because each has it's own internal, smaller state and just it notifies listeners when some action takes place. Nobody cares about what's going on there until something happens and then you just get concrete data.
Going with #1 helps you deal with complexity in your application while allowing you to reuse them in other contexts.
I have a ng-repeat that generates around 300 rows. I can't implement infinite scrolling since i need all the rows present on the page. For each row there are 3 elements.
When the page loads, i get all the rows from the database and if the element exists i display it, if not i have the option to add it by clicking on the place where the element would otherwise be. When clicked a form is displayed right under that element.
The form has 4 inputs, which is quite a lot of html. Now since we have two-way data binding, and we are inside the ng-repeat isolated scope, i can't use one form for all 3 elements (since the values in the inputs would be shared), i would need one for each. Considering the amount of rows, rendering so many forms takes more than i'd like.
To get a better idea of what i'm working with (visually, the code is not relevant anymore) http://plnkr.co/edit/xNYUbi?p=preview
I want to stick to the form dropdown under the add element option, so making a modal isn't an option.
How should i approach this problem?
I'm not certain I understand the specific use case here so I will give some generic advice that I hope helps. When working with lots of data angular, there are a number of options:
ng-grid: Has an edit mode and paging so with the correct settings you can pull down all your data, set the data source for the grid and the performance should still be pretty good.
ng-repeat: If you have to have a custom U/I or you need additional functions in your U/I, ng-repeat is about as good as it gets. As long as you don't have nested repeats (can be bad) and you craft your UI carefully you should mostly be all right.
Assuming that ng-repeat is still too slow you could think about implementing some form of paging or ng-infinite-scroll. With either option you can still load the entire data set initially and then display it in chunks rather than all at once.
At the end of the day - if the performance is unacceptable when you try to add all the elements to the DOM the only real solution is to alter the way those elements are added or simply don't add them at all (which is where all the above solutions really lead you). This might require talking to your client or going through a bit of re-design, but in the end it should be worth it. Best of luck!
Background: I'm currently developing the client side for a web application, using JavaScript, with jQuery and Backbone.js (these are required by the proponent).
This is an application to visualize and edit data, in a graphical mode (through interactive diagrams representing the data, mainly).
Terminology: Said data is under the format of multiple documents, each containing a list of items.
For the purpose of this question, let the items be composed by an identifier, a textual description, and links to items in other documents. Links should be symmetric (i1 -> i2 exists if and only if i2 -> i1 also exists).
The Current Goal: In this phase, the application should be able to read two documents, display both lists side by side, and then draw lines, connecting the items between both documents, according to their links.
These lines should be editable. In other words, the user should be able to create new links, or remove existing ones (reflecting the changes on the item models).
These documents can be somewhat long, say, some dozens of items (maybe a few hundreds, in a realistic scenario). Of course, the page will be scrollable, to allow the user to see everything.
Also, for user convenience, there should be a slider to scale the view (allowing zoom in/out effects, so the user is given a global and a local view, being the latter more adequate for editing and the former for analysis).
Furthermore, the user should be allowed to hide particular items (useful when an item has many links, creating visual rubbish).
What I've managed to do:
Read data and map it to Backbone models and collections;
Display both documents side by side (Backbone views), with item connections;
Allow interactivity on these connections (drag-and-drop to create lines, click to remove), reflecting changes on Backbone models;
Hide particular items;
Scale effects.
I've achieved this using SVG, after coming across jsPlumb.
The Problem at Hands: The application still needs adjustments (emphasis on the scaling effects). Regardless, I found jsPlumb to be comfortable to work with. However, rendering performance seems to be a little lacking, when using the slider (it's possible that the slider steps are too small, thus firing too many events).
The proponent suggested that I try, instead, Sankey diagrams, to represent this kind of data. They also suggested that I try Sankey by tamc, based on Raphaƫl.js.
Of course, the visual factor is also contributive.
My question(s): Does this library have a good compatibility with Backbone? Possibly, if I use the resulting SVG elements as Backbone views' elements.
Also, does any of the two have a significant rendering performance advantage over the other?
On a final note, are there any other libraries more adequate to this scenario, worth the time of rewritting the application, that I might suggest to the proponents?
The project is going on, and I ended up using Sankey by tamc, with some extra work of my own, to better adapt it to this particular case.
I got a pretty big form on a wpf page. I'm putting it together on a Grid, but all the element clutter the page. I figured i'd split out the form into smaller usercontrols and then piece it together on the page as one form. That didn't quite work: SharedSizeScope on a Grid makes the form 'dance'
I could break up the form into a 'wizard style' page, with a next button - dealing with each user control on its own, but i'd rather not break it up into several pages because the end user is used to having it all on one page. Also the validation/storing of data is really a big-bang operation, making it harder to provide feedback if something goes wrong in one of the first pages/usercontrols.
So what now? I'm really tempted to just put all the small elements directly on the page in one big grid. I just feel it's wrong - it will be a maintenance nightmare - i even started thinking 'i wish there were some kind of #region tag in xaml' - that means i know i'm wrong ;)
What can i do?
I would strongly recommend to use nested container controls, like Grids (or other Panels) inside other Grids inside more Grids etc.
It is very common to have several nesting levels, and thus hierarchically split a complex layout into multiple less complex sub-layouts. This makes your layout significantly simpler compared to one big container that tries to do it all (see your failed ShardSizeScope approach).
Once you have created a sensible hierarchy of containers, you may easily use the Visual Studio XAML editor's code collapsing feature to keep track of all your XAML.
In CakePHP I have a layout created and named default.ctp. In that layout I have a sidebar with some blocks and there're some statistics taken from the database.
My solution: I just created model called Sidebar.php and there're some functions, then I set up data in controller to display it in layout. Is this the best solution? As far I know, I will have to re-set every data in every controller, so need suggestions how to solve that.
Bear in mind that this is coming from a 10,000' level - I know nothing of your particular circumstances, but IMO it's not the best solution. I say that because you've created a model that represents a presentation component. If it were me, I'd probably look at using an element for display. Displaying dynamic components gets a little dodgy, but can be done without violating the MVC "covenant".
Your models should represent your domain entities (you've mentioned nothing about what your stats represent, so I won't offer any specific examples), not how they're presented.