OpenF2 / F2

Redefining web integration for the financial services community
Apache License 2.0
129 stars 62 forks source link

Tangible Container #167

Open montlebalm opened 10 years ago

montlebalm commented 10 years ago

I believe there could be both tangible and philosophical value in making the container a real object that is instantiated. Today, the Container is simply an idea representing the logic that loads Apps.

What if instead, we required Containers to be created like so:

require(['F2Container'], function(F2Container) {
  new F2Container({
    loadScripts: function() {},
    ui: {
      modal: function() {}
    }
  }, function(F2) {
    // F2.apps == app registry
    // F2.secretSauce == container only property

    // Container logic
  });
});

The gist is that you would instantiate F2Container and pass it your config and your container implementation. The library would instantiate a new version of F2 for you. This would allow us to localize configs in a multi-container solution. It also allows us to give containers special instances of F2 that have additional properties like an app registry. Previously, we've locked down similar functionality via tokens.

The last advantage is that it makes the Container a corporeal function we can point to when someone is learning the library.

My current thinking is that events would remain global, so any App could talk to any other App regardless of which container loaded them. I was thinking that the app registry would be localized to each container so different configs could be used to load different apps.

In conjunction with this, I think we should move towards a "no global" use of F2. Everyone wanting to make use of it would need to instantiate a controller or the F2Factory function.

ilinkuo commented 10 years ago

I believe there could be both tangible and philosophical value in making the container a real object that is instantiated.

+1 on the thought.

Ideally, the Container would really just be a special type of App, and F2 would move toward a vision of multiple Containers and even nested Containers.

brianbaker commented 10 years ago

If I load AppA into F2Container1 and AppA into F2Container2, would the expectation be that (due to AMD) AppA will have only been loaded once? Or by way of context will the apps be loaded once per container?

markhealey commented 10 years ago

+1 for @montlebalm's thought, too.

@ilinkuo, your blog post on the Borg Container is one I've read before and it explains this problem space quite well, especially with the diagrams. We're going to add some diagrams like this plus some others that cover 'lifecycle' in the revised F2 docs. Thanks for re-linking, there's a lot of parallels to issues you wrote about and problems we've solved with F2. Couple comments:

  1. In F2, we've also made the same assumption for #1 because there isn't anything tangible with an F2 Container—it's pure logic and little else—and we fell back to simply describing one as "encompassing the entire page". That's served us well describing F2 to non-technical individuals. (Technically, of course, using F2 you can place apps in any dom node on the page without needing control of the page itself. There are no layout managers or UI patterns to follow, just script that injects some resources including HTML into the dom.) This is why I like @montlebalm's idea for making the container something more than it is today.
  2. I think you know this already but for others reading: F2 solves the subcontainer problem you noted by requiring the module pattern be used in CSS.
  3. It certainly wouldn't be elegant, but there's nothing preventing someone from writing an F2 App that is an F2 Container and is responsible for loading its own apps. I see the differences you noted between containers and widgets, but I didn't see any detail on what advantages would be gained by making a container a special type of app.
  4. I think your points on #4 are largely working through semantics: a dom node is a containing element for a widget therefore the widget is in a container, even if that dom node is <body>. It's what the container offers the app that makes it different (such as events, isolation, data, etc.).
ilinkuo commented 10 years ago

I didn't see any detail on what advantages would be gained by making a container a special type of app.

Let me first say I'm not necessarily recommending that you do this, because it's A LOT OF WORK.

The simplest kind of Container is just a domNode capable of containing a single App. It would be reliant on the F2 framework to do its loading.

As Containers get more complicated, they can have LayoutManagers, EventManagers, ClientDataManagers, etc. to set up their individual policies. For example, Bloomberg could create its own Bloomberg Container where all the Bloomberg apps could be loaded inside and they could freely share the same Event space. F2 Apps outside of the Bloomberg Container could only communicate to the inside Apps through the Container itself. The Bloomberg Container itself would be in an iframe for security, but the individual Bloomberg Apps within Bloomber would be non-framed and could be dragged and dropped within the iframed Container without any issues.

As for the advantage of making the Container just another App, my opinion is that this will turn out to be easier in the code architecture. By analogy, in the discussion of AMDifying F2 #151 , there was a question of how to handle loading layers throughout the life of the page as new modules/Apps come in. In the standard use of AMD, all layers are loaded at the beginning. As I thought about the problem at first, it seemed that a whole infrastructure would have to be built out to manage layers which are loaded later. But as I dug deeper, I realized that the layer management problem was very similar to the module management problem, and that if I simply packaged layers as modules, I could reuse most of AMD's module management for layer management. I suspect that in the once you start dealing with multiple F2 Containers, you'll find that the problem has many parallels with multiple F2 Apps and you'll want to handle both very similarly.