We have to implement multiple-document-interface web application. Each document has to live in a separate tab (but on the same page, it has to be SPA). There may be up to 50 opened tabs simultaneously and application should give ability to group tab panes by modules.
One of our options were to use AngularJS for this task. We like the way Angular handles partial views, structures application by using modules/controllers and performs dependency injection.
After digging in for couple of days, we've figured out that there may be some problems with the way bindings work: there is no easy way to prevent angular from watching tabs, which contents are not currently displayed to the user. You can imagine situation when user will have around 20 opened tabs and this whole thing becomes slow as hell! Also our application is very grid-heavy, so for grids I think we should avoid ng bindings at all.
We were thinking about ng-view and the way it recreates DOM on each activation ... this looks overkill and will force us to put all UI state into the view-models, even for scroll-bars :)
Can you suggest some possible ways to improve performance with Angular and MDI? Maybe we should even consider using some other ui-framework/set of tools to achieve same results?
What's important:
modularity (AMD)
dependency injection
declarative bindings (we do like how angular and knockout solved those problems)
MVVM/MVC
ability to create multiple instances of the same controller (open multiple "details" tabs for each specific item from the grid, for example)
modularity - Angular has it's own modularity rules/patterns which are good if you want to conform to them, but if you want to make something modular in a different way, eg... allow forms to be self contained so that multiple instances of them can dynamically be opened concurrently it's quite difficult
dependency injection - Angular allows you to write code that you can inject other into, but you cannot inject Angular, it seems an oversight that you cannot test your code isolated from Angulars?
declarative bindings - yep, the way Angular binds literals within HTML with the JS code makes it really hard to create MDIs with multiple concurrent instances of a single form. You really need to dynamically create your form instances with their own identifiers (in addition to Angulars) then scope your own identifiers within the bounds of a shared set of JS files (which is what you want), however then Angular's binding will get in the way of each instance if you continue to use Angular's bindings - alternatively you can try modify the HTML dynamically get Angular to refresh it's bindings.
Basically anything to do with MDI is harder than it needs to be with Angular and it's worth looking at alternatives for such projects before hand.
AngularJS can indeed be heavy on a big application, but only when you make a change inside the $scope. The bigger part of this time is spent looking for modification by dirty checking.
If you keep an AngularJS application inside a non active tab, a dirty checking can only happen after a outside event (like a WebSocket message). You can optimize your application to remove those listener when the tab is not focused.
If you follow the best practice of AngularJS, performance issues with a lot of pages opened should not be a problem. The bigger performance problem of AngularJS come with very big amount of data inside its $scope, but there is a lot of solutions proposed all over the internet.
Related
I am starting to write my first web app with Node.js and Express. I have two approaches in mind.
Create two sets of routes. One that sends JSON, one that renders the page using a templating engine
Create a static website that makes API calls to the backend using AJAX, and have only routes for the API.
I understand that approach #2 depends on AJAX support in the browser, but if this was your project, based on the advantages and disadvantages of each approach, which would you choose and why?
If I am reading it right, both options #1 and #2 first set of routes is an API that returns JSON rather than sends it.
Assuming that in #2 you wouldn't create static pages with JavaScript doing AJAX calls, but rather still use express static routing like app.use('/', express.static(path.join(__dirname, 'dist'))); the difference between 2 approaches isn't that big.
Unless you already know some supported template language, such as mustache the cons are that you have to learn one and before that pick one (which isn't always an easy task from my experience!).
If you don't know one, depending on your application, you might still benefit from learning and using one. As an example you can think of a very generic UI where a single template could be reused very many times - like a generic database UI similar to, say well known phpmyadmin.
In case of static routing, you can achieve similar results by using a JavaScript framework which has components or templates, such as angular. If you aren't planning to use one, that could result in a lot of code duplication of otherwise re-usable widgets. And even when using one I can imagine a case when template engine would result in less code (or less files in your project at the very least). Not sure though if it's going to be easier to navigate and moreover to cover with tests when the project grows.
Without knowing more about your project it is hard to give more advice.
If the product you're developing is primarily static content with some dynamic pieces here and there, I'd recommend serving HTML from your backend via a templating system. A good example of this would be a blog. You'll end up with better SEO and there are less moving pieces to grok in this approach.
However, if you want to develop a single page application, I recommend using your backend entirely as an api, and writing your client side logic entirely in React/Vue/Angular/whatever. Single page applications have their front ends written entirely in javascript, and are best suited to highly dynamic, "app like" experiences online. Think gmail or facebook.
In my current project we use both approaches. Many views are static and data is obtained from API calls (we just use angular) or bootstrapped values (we load some objects with template, like user roles etc.)
However, some views are rendered on server site, because it easily allow us to dynamically inject values, tokens or other supporting data without making extra requests.
So, I vote for flexibility
I have to decide on the view layer technology to use with Spring MVC 3 and I came across Thymeleaf.
Has anybody worked with Thymeleaf or has any experience with it. What will I gain and miss if I happen to choose it to work with Spring 3.
I wanted my front end designers to feel comfortable was why I was thinking if I could use thymeleaf with Spring 3 and still have all the functionalities we get with JSPs + Spring MVC 3.
Thymeleaf and Spring are a very nice match. The spring integration of Thymeleaf is done as it's supposed to be and it was nicely documented how to get started.
I use this combination since one year in several projects and I'm still happy with the choice I've made at the time.
Thymeleaf propagates the so called "Natural templating", which means that the templates can be viewed without the template engine, they are html files with additional tag attributes which browsers just ignore.
This means that a webdesigner can design the page, hand it over to the developer and get back again if changes to the layout have to be made.
While I liked this idea a lot in the beginning, I soon realized that, as developers, we tend to create components to be reused. This results often in templates having either not alot to display or also an extreme amount of elements.
Imagine some switch statement in a table cell component which renders either checkbox, textfield, select box, and so on. The table template including this cell fragment does not resolve it without an engine. Or imagine the header fragment with all the style and js declarations. Css will not be available in plain file mode.
But you can add additional html tags and remove them during processing. So natural templating is still possible. Just a lot to write :)
There are support extensions around solving this issues (using JS to pull in the fragments for example) but I havent used them as my applications are normally deployed within 30sec and I'm even able to change the templates on the fly without a redeploy.
After you also have a quite nice eco system around thymeleaf. The ability to extend Thymeleaf is done in a way I really enjoy! (Having written two smaller extensions myself).
I prefer the layout dialect instead of the include approach. That's a matter of taste i would say.
Choosing Thymeleaf over Plain JSP is clearly favorable from my point of view. Take a look at the webpage and decide for yourself ;)
I'm working with Spring 3 and Thymeleaf for a year and think it's a good choice. I came from Grails and Play and look for a good alternative and created FuWeSta. You can look at the rudimetar sample-app.
As I'm learning about Sammy.js I read that you can have several Sammy.js applications in the same page, each bound to a different element (i.e. div). I would like to understand why would this be useful.
I read in another post that only forms inside a bound element will trigger the route change, I'm thinking this could be used to modularize your application. Is there another use case beside this? Could you provide an example of how to modularize your application in this way?
We implemented a component similar to Sammy in our Silverlight application some time ago. The similarity is in that both represent a kind of a simple browser that can be bound to a UI region. The approach gave us several benefits:
We had an extensible way to add new content implementations. I mean that we could add plugins to our app that contained new forms/views which the application core had no knowledge about.
We could easily implement composite views, e.g. dashboard that were able to show any view implemented in any module. Including themselves. (A-ha, we had created recursive dashboards that worked until the app hit the memory limit. Kind of Inception. :))
Sammy can be used to reach these goals as well.
However, you must understand that from all Sammy applications running on a page, only one can be bound to the browser location bar. Others will have their location visible only to javascript, or you'll need to render location bars for them on the page.
I just started a new GWT project for a client and I'm interested in hearing people's experience with various GWT MVC architectures. On a recent project, I used both GXT MVC, as well as a custom messaging solution (based on Appcelerator's MQ). GXT MVC worked OK, but it seemed like overkill for GWT and was hard to make work with browser history. I've heard of PureMVC and GWTiger, but never used them. Our custom MQ solution worked pretty well, but made it difficult to test components with JUnit.
In addition, I've heard that Google Wave (a GWT application) is written using a Model-View-Presenter pattern. A sample MVP application was recently published, but looking at the code, it doesn't seem that intuitive.
If you were building a new GWT application, which architecture would you use? What are the pros and cons of your choice?
Thanks,
Matt
It's worth noting that google has finally written out a tutorial for designing using the mvp architecture. It clarifies a lot of the elements from the google i/o talk listed above. Take a looK: https://developers.google.com/web-toolkit/articles/mvp-architecture
I am glad this question has been asked, because GWT desperatley needs a rails-like way of structuring an application. A simple approach based on best practices that will work for 90 % of all use-cases and enables super easy testability.
In the past years I have been using my own implementation of MVP with a very passive view that enslaves itself to whatever the Presenter tells him to do.
My solution consisted of the following:
an interface per widget defining the methods to control the visual appearance
an implementing class that can be a Composite or use an external widget library
a central Presenter for a screen that hosts N views that are made up of M widgets
a central model per screen that holds the data associated with the current visual appearance
generic listener classes like "SourcesAddEvents[CustomerDTO]" (the editor does not like the real symbols for java generics here, so I used thoe brackets), because otherwise you will have lots of the same interfaces who just differ by the type
The Views get a reference to the presenter as their constructor parameter, so they can initialize their events with the presenter. The presenter will handles those events and notify other widgets/views and or call gwt-rpc that on success puts its result into the model. The model has a typical "Property[List[String]] names = ...." property change listener mechanism that is registered with the presenter so that the update of a model by an gwt-rpc request goes to all views/widgets that are interested.
With this appraoch I have gotten very easy testability with EasyMock for my AsynInterfaces. I also got the ability to easily exchange the implementation of a view/widget, because all I had to rewrite was the code that notified the presenter of some event - regardless of the underlying widget (Button, Links, etc).
Problems with my approach:
My current implementation makes it hard to synchronize data-values between the central models of different screens. Say you have a screen that displays a set of categories and another screen that lets you add/edit those items. Currently it is very hard to propagate those change events across the boundaries of the screens, because the values are cached in those models and it is hard to find our whether some things are dirty (would have been easy in a traditional web1.0-html-dumb-terminal kind of scenario with serverside declarative caching).
The constructor parameters of the views enable super-easy testing, but without a solid Dependency-Injection framework, one will have some UGLY factory/setup code inside "onModuleLoad()". At the time I started this, I was not aware of Google GIN, so when I refactor my app, I will use that to get rid of this boilerplate. An interesting example here is the "HigherLower" game inside the GIN-Trunk.
I did not get History right the first time, so it is hard to navigate from one part of my app to another. My approach is not aware of History, which is a serious downturn.
My Solutions to those problems:
Use GIN to remove the setup boilerplate that is hard to maintain
While moving from Gwt-Ext to GXT, use its MVC framework as an EventBus to attach/detach modular screens, to avoid the caching/synchronization issues
Think of some kind of "Place"-Abstraction like Ray Ryan described in his talk at I/O 09, which bridges the Event-Gap between GXT-MVC and GWTs-Hitory approach
Use MVP for widgets to isolate data access
Summary:
I dont think one can use a single "MVP" approach for an entire app. One definetly needs history for app-navigation, a eventbus like GXT-MVC to attach/detach screens, and MVP to enable easy testing of data access for widgets.
I therefore propose a layered approach that combines these three elements, since I believe that the "one-event-mvp-system"-solution wont work. Navigation/Screen-Attaching/Data-Access are three separate concerns and I will refactor my app (move to GXT) in the following months to utilize all three event-frameworks for each concerns separately (best tool for the job). All three elements need not be aware of each other. I do know that my solution only applies for GXT-projects.
When writing big GWT apps, I feel like I have to reinvent something like Spring-MVC on the client, which really sucks, because it takes a lot of time and brain-power to spit out something elegant as Spring MVC. GWT needs an app framework much more than those tiny little JS-optimizations that the compiler-guys work so hard on.
Here is a recent Google IO presentation on architecting your GWT application.
Enjoy.
-JP
If you're interested in using the MVP architecture, you might want to take a look at GWTP: http://code.google.com/p/gwt-platform/ . It's an open source MVP framework I'm working on, that supports many nice features of GWT, including code splitting and history management, with a simple annotation-based API. It is quite recent, but is already being used in a number of projects.
You should have a look at GWT Portlets. We developed the GWT Portlets Framework while working on a large HR Portal application and it is now free and open source. From the GWT Portlets website (hosted on Google code):
The programming model is somewhat similar to writing JSR168 portlets for a portal server (Liferay, JBoss Portal etc.). The "portal" is your application built using the GWT Portlets framework as a library. Application functionality is developed as loosely coupled Portlets each with an optional server side DataProvider.
Every Portlet knows how to externalize its state into a serializable PortletFactory subclass (momento / DTO / factory pattern) making important functionality possible:
CRUD operations are handled by a single GWT RPC for all Portlets
The layout of Portlets on a "page" can be represented as a tree of WidgetFactory's (an interface implemented by PortletFactory)
Trees of WidgetFactory's can be serialized and marshalled to/from XML on the server, to store GUI layouts (or "pages") in XML page files
Other important features of the framework are listed below:
Pages can be edited in the browser at runtime (by developers and/or users) using the framework layout editor
Portlets are positioned absolutely so can use scrolling regions
Portlets are configurable, indicate when they are busy loading for automatic "loading spinner" display and can be maximized
Themed widgets including a styled dialog box, a CSS styled button replacement, small toolbuttons and a HTML template driven menu
GWT Portlets is implemented in Java code and does not wrap any external Javascript libraries. It does not impose any server side framework (e.g. Spring or J2EE) but is designed to work well in conjunction with such frameworks.
We have two separate web-apps, say 'retailUI' and 'bulkUI'. These two are basically two separate web applications (within the same business domain). Now, the requirement has been given to us to make the two work together in one page with a Tabbed interface (as a PoC).
My problem is that both the applications span over a number of JSP pages for navigation.
Is there a way that I can achieve this using some framework or some other approach?
If you want to keep the two applications as much as possible the way they are now, without rewriting them entirely, you gotta use iframes. That means the content of each tab is actually an iframe.
For such cases I found of great use a ExtJS user developed component, ManagedIFrame which as it's names suggested is a managed iframe. Using it, your iframes can interact with each other(for instance sendind messages from one to another, listeners etc.)
Carefully planing the listeners and their registering by checking whether the peer is there you could build this integrated application without rendering the two separate applications unoperational when ran standalone.
Sounds like your easiest bet is to use Frames. For this, each of your two web apps will be frames of a wrapper web app. You would then hide or show the frames based on which one you want to be active.
This would allow you to have seperate navigation in each, and the two apps don't necessarily have to know anything about one another.