aurajs / aura

A scalable, event-driven JavaScript architecture for developing component-based applications.
MIT License
2.94k stars 256 forks source link

Exposing sandbox in complex widgets #285

Open Giuliano84 opened 11 years ago

Giuliano84 commented 11 years ago

Hi there,

we worked with Aura widgets since early days using them in a BackboneJS web application. Last changes on Aura left us some doubt about what we should change on our approach since Aura was pretty much binded to Backbone before. Previous Aura version exposed a global "sandbox" that could be reached from anywhere by declaring it in the RequireJS' "define" section. After the update the sandbox is availaible through this.sandbox but it looks like it is somehow injected inside the widget main.js file. Our widget, build as independent applications, has several views and models that need to talk to the sandbox (to work with Backbone functionalities), to be initialized. They were defined like this:

/* Widget main class*/
define(['./views/app'], function (AppView) {
  return function () {
    new AppView({
      el: 'div [data-aura-widget="editor-admin-showone"]'
    });

   this.sandbox.emit('admin-showone.initialized', 'Initialized Admin ShowOne');

  };
});

/* App Module */
define(['sandbox', 'hbs!../templates/show_one', '../models/User'],
        function(sandbox, Template, User) {

            var AppView = sandbox.mvc.View({
                initialize: function() {
                    this.render();
        }

With the actual Aura implementation widget raise errors at load-time, it looks like requirejs cant reach the sandbox, we found a workaround forcing its exposure calling a define of the sandbox inside the Aura start function. In this way our widgets can talk with the sandbox again.


  Aura()
    .use('extensions/aura-backbone')
    .use(function(app) {
      define('sandbox',[],function(){return app.createSandbox();});
    })
    .start({ widgets: 'body' }).then(function() {
      console.warn("Aura started !");
    });

Is this a good way to handle it Oo should be widget's main.js the one in charge to expose all the global Aura object to the other classes and functions?

Maybe you have any example of more complicated widgets that looks more like a small backbone application.

Best Regards,

Giuliano84 commented 11 years ago

I had a further look on our issue and faced @sbellity reply to an older issue where our second hypothesis is kind of shown

main.js

define(['./model'], function(ModelFactory) {
  return {
    initialize: function() {
      var Model = ModelFactory(this.sandbox);
    }
  }
});
model.js

define(function() {
  return function(sandbox) {
    return sandbox.mvc.Model.extend({ ... })
  }
});

Passing the sandbox to inner models and views of a widget would be necessary in case of an inner view or model needs to emit an event against the sandbox. Did someone find out if this can be considered a practice?

brommer commented 11 years ago

Hi @Giuliano84 we are doing it exact the same way in our project.

Regards

addyosmani commented 11 years ago

In my experiments with the post aura-express merge I've found myself doing something quite similar with inner models. It would be useful for us to document the approach listed as I'm sure others will wonder about it too.

Did you find this approach straightforward enough to work with once you had reached it? I ask as if there is more than can be done to simplify the solution it would be good to discuss before we label it as best practice.