My website is built with Angular2. Imagine it as a big dashboard with a lot of modules. Sometimes information from multiple modules are required at the same time - therefore I want to allow my users to open a module in a new window. A real-world example for this is the video container of Hangout.
From my research there would be 2 ways to do this:
I open the route of the selected Ng-Component in a new window. As a result angular would reinit all services. To keep my data consistent I would need find a way to sync the instances. Maybe some kind of service that writes all attributes to localStorage?
This is somehow the way GoldenLayout implemented the Popouts.
I could init my component in window A and hide it - Now open a new window (B) and pass a copy (Css, HTML, Data) of my component to it. This would mean that I only need to sync the mirrored component, but I am not sure if this is good architecture.
Which way would you go to solve the described problem and are there more elegant solutions?
Related
A client has tasked me with refactoring their React app to support multiple screens. I have some ideas on how to approach this, and would like to get some feedback to see if I am on the right track.
The problem:
We have a relatively complex React app, and the client feels that splitting the app across multiple windows will make for a better UX.
As example of this split-screen set up, imagine that window 1 shows some data, and window 2 contains UI elements that allow you to filter that data. In this manner, the app is split across 2 windows.
(The 2 browser windows is a hard constraint imposed by the product owner. Other options like grid layout managers are not considered.)
The solution (so far):
We need to share state across two browser windows. To do so, we can use:
Local storage to keep track of state and use StorageEvent listeners to coordinate state changes between the two windows.
We can also use some of the web APIs designed to pass data between windows including: shared web worker, broadcast channels, and window.postmessage(). I learned about these in Blake Zimmerman's presentation here, PDF ~2mb.
This framework - neo.mjs, which uses web workers. I would rather not abstract the low-level details to a framework, because I am not familiar with web workers myself yet.
The question:
Is there something I am missing? Are there other tools I can use to share state between windows? Any good articles I can read?
I am also having trouble visualizing how to structure the React app to account for multiple displays. The best I could come up with is something like this:
<Main>
{isComponentAShown && <ComponentA/>}
{isComponentBShown && <ComponentB/>}
</Main>
where isComponent_X_Shown dictate which components the browser window should be displaying at any one time. These boolean flags will be part of the state shared by the two browser windows. Is there a better way to organize the App layouts to account for dual screen?
Thank you!
I have a bundle of older ExtJs components that drive the UI, store management, and application logic in something that prior to the world of MVC I'd have called an application. I'm in the process of rewriting it, and wanted to take advantage of ExtJS MVC if possible.
The one thing that makes this unique from the tons of guides I'd otherwise be working from is that my Ext app doesn't own the whole page - instead of a full page viewport onready I have a modal Ext.window.Window that runs on an event from other non-ext javascript on the page.
I'd like to migrate this into a coherent ext application if possible, but as they seem to only properly launch when ext is ready I'm questioning if this is the right tool for the job.
My leading idea right now is to initialize the application on page load, but not actually render any views - exposing a static method on the app the external js can call to render and start my app's lifecycle on demand. Is this a good idea? Is there a better option I'm missing?
Yes, it is a very good idea. I have written an example of simple login system where the application is not actually started before the user logs-in.
It is very similar to your way in that that there is a method you call to actually start the app.
I'm new on angluarjs and trying to build an example-application.
This application is divided into 3 parts/sections:
A.) map
B.) "received"-area
C.) "send"-area
Every section has its own layout/view-area, not visible at the same time.
In part B.) you can load information from server by click or automatically, which will be displayed in part "B.)" as text and in section "A.)" as map-marker.
Additionally you can click inside section "A.)" to set a new marker.
In section "C.)" there is a send button to take the new marker from "A.)" in order to send this to the server.
Currently: all of the sections (A,B,C) are angular modules/own apps.
But I don't know, if that is the right way/best practice.
An other way could be a single module for the whole page an 3 controllers (A,B,C) which handle the logic for sections A,B and C.
What is the right way in angularjs?
From your description, I recommend designing it as a single AngularJS app with separate controllers for each view. It sounds like you would benefit from using an angular service to handle the client-side business logic and cache any shared data/models that could be used by the views. It is a best-practice in Angular to keep the controllers pretty lean and focused just on the view setup/binding and orchestrating the access to the services.
After searching the way to get some inspiration, i decided to realize the following think:
For all the self-made code, I use one module for the whole application and for all the external things, bundled with external plugins and services, I take a different module. This means: pne module for each "service-plugin bundle" (like google API & angular-google-maps plugin)
So I can switch the module, if the external service does not work, etc.
Looking at my example in the question this means:
Application part A: the map and all the map-specific things (set new marker, draw circle, etc) are insight a map-module. If I decide to use open street map instead of google maps i will plug in an new maps module
Application part A and B: this is my "main" app module with different controllers.
Im trying to share data between 2 views. I need to use the 2 views at the same time on two different machines. One is controlling the other(ex: a counter) 1st view has next(+1) and the other just displays the result. I want the data to synchronized/binded. I do not want to have to refresh the 2nd page or to have to pull data with a timer or otherwise.
My idea was to use ng-view and routeProvider, I know that when the view changes the scope is cleared so I tried to use a parent controller/scope, the data is shared but I have to refresh the page on my 2nd view. I tried a service, same thing. I tried to $watch the result of the service but on the second controller/view no event is picked up so the view doesn't update.
what is the way to go? I was thinking about broadcasting or emit a custom event and trying to catch it, will that work? Am I just not binding to the service correctly? Would ui-router work better? I feel there should be an easy way to do this.... Im not seeing it! Please help if you can.
One of the simplest (in my opinion) implementations of client-client communication is using WebSockets. While that does have compatibility limitations (some browsers), that can easily be overcome by using a library like socket.io. Also, it's easy to write an Angular wrapper/service over socket.io that can be shared across components of your app, or even different modules.
It's also pretty simple to write a Node backend with socket.io
This might be a good read.
I would suggest you to focus on pushing stream rather than sharing it. Some how you need to push stream to second view which is changes in first view.
You may want to check this
Is there some way to PUSH data from web server to browser?
I am currently working on a large enterprise web platform which loads different web applications (html/js/silverlight) as views so it is almost like a container or a framework for accessing different types of web applications.
We are currently reviewing the migration to Angular however there's one problem (at least) which we can't address.
in the current non-Angular version when a user loads Application-A from within the framework and let's say types "ABC" in a text box then he decides to navigate away and load Application-B and after using that application when navigates back to Application-A he can still see "ABC" in the textbox in other words he has "Persistent Workspace" so every app that he loads whether it be Silverlight or Html/JS has the ability to be kept loaded into the memory.
Regardless of the right or wrong of this approach can anyone think of the way this can be implemented in Angular? a simple overview is enough.
[UPDATE]
Please note that we are dealing with iFrames for each of the web apps we currently load, so there's no model that we can persist to the browser storage or elsewhere. if all our apps where html/js based then we would have no problems as we could serialize the state of each view but since some are in Silverllight we can't do that. hope this clarifies.
Thank you all.
You can always synchronize Angular's state with the local storage of the browser. So there will have to be a unique key for every field in every form and use something like this.
Alternatively, you can listen for the $routeChangeStart event (docs) from within each controller that cares to save status. Then the controller can decide to serialize its state (or not) to the local storage. On controller initialization, the saved state must be retrieved.
Solutions involving the browser's local storage will not affect the server but will not be available to the user when he/she uses another computer. Otherwise, you should listen to the route events as before, but synchronize the "persistent workspace" with the server (slower, more development time).