Skip to content

Instantly share code, notes, and snippets.

@montlebalm
Last active December 22, 2015 16:19
Show Gist options
  • Save montlebalm/6498896 to your computer and use it in GitHub Desktop.
Save montlebalm/6498896 to your computer and use it in GitHub Desktop.
F2 AMD - Example usage of an F2 container and app using AMD
// --------------------
// Example AppClass
// --------------------
define("com_markit_header", ["F2.BaseAppClass"], function(baseClass) {
var HeaderClass = function() { };
HeaderClass.prototype = new baseClass;
HeaderClass.prototype.beAHeader = function() {
alert("\"I'm OG\" -" + this.appId);
};
return HeaderClass;
});
// Register the apps we'll want to load at some point
require.config({
f2: {
appConfigs: [
{ appId: "com_markit_header", manifestUrl: "http://markit.com/f2/apps", enableBatchRequests: true },
{ appId: "com_markit_disclaimers", manifestUrl: "http://markit.com/f2/apps", enableBatchRequests: true },
{ appId: "com_bloomberg_worthless", manifestUrl: "http://bloomberg.com/f2/apps" }
]
}
});
require(["jquery", "F2.Events"], function($, events) {
var $wrapper = $("div.wrapper");
var pageTicker = $wrapper.attr("data-ticker");
// --------------------
// Load apps immediately
// --------------------
require([
"F2App!com_markit_header",
"F2App!com_markit_disclaimers",
"F2.Defer"
], function(appHeader, appDisclaimer, defer) {
/*
* Here's what's going on behind the scenes
*
* // Make the promise
* var deferred = $q.defer();
* var appHeader = deferred.promise;
* appHeader.context = appConfig.context;
* appHeader.root = document.body
* onload(appHeader);
*
* // After app loaded
* deferred.resolve();
*/
// Set some app context
appHeader.setContext({ ticker: pageTicker });
appHeader.setRoot($("div.head-container")[0]);
appDisclaimer.setContext({ sections: ["102", "405", "555"] });
appDisclaimer.setRoot($("div.disclaimer-container")[0]);
// Add a loading indicator
$wrapper.addClass("loading");
// Watch for all to be loaded
// NOTE: since callback params are promises, we can treat them as deferreds
// NOTE: see https://github.com/kriskowal/q for more info
defer.all(appHeader, appDisclaimer, function() {
$wrapper.removeClass("loading");
});
});
// --------------------
// Load apps on demand
// --------------------
$("ul.menu-of-apps").on("li[data-appid]", "click", function(e) {
var appId = e.currentTarget.getAttribute("data-appid");
var appContainer = $("div.app-container");
require(["F2App!" + appId], function(app) {
var $newItem = $("<li class='loading' />").attr("data-appid", appId).appendTo(appContainer);
app.setContext({ ticker: pageTicker });
app.setRoot($newItem[0]);
defer.all(app, function(appHtml) {
$newItem.removeClass("loading");
});
});
});
// --------------------
// Log app usage
// --------------------
events.on(events.Constants.APP_LOAD, function(appId) {
console.log("DEBUG: loaded app", appId);
});
events.on(events.Constants.APP_REMOVE, function(appId) {
console.log("DEBUG: removed app", appId);
});
});
define("F2.BaseAppClass", ["F2.Events", "F2.Defer"], function(events, defer) {
var AppClass = function() {};
// Init function that will be called by F2 automatically
// You probably don't want to override this, but you can
AppClass.prototype.init = function(appId, instanceId, context) {
var self = this;
this.appId = appId;
this.instanceId = instanceId;
this.context = context || {};
// Dispose of ourselves if asked
events.on(events.Constants.APP_REMOVE, this.instanceId, function(instanceId) {
if (self.instanceId == instanceId) {
self.dispose();
}
});
// Tell the world we've arrived
events.emit(events.Constants.APP_LOAD, this.appId);
};
// Automatically reload this app in place
AppClass.prototype.reload = function(context) {
var self = this;
// Load ourselves using the F2App plugin
require(["F2App!" + this.appId], function(app) {
app.setContext(context);
app.setRoot(self.root);
// Remove the old instance
defer.all(app, self.dispose);
});
};
// Clean up after ourselves
AppClass.prototype.dispose = function() {
// Unsubscribe to all events
events.off(this.instanceId);
// Remove ourselves from the DOM
this.root.parentNode.removeChild(this.root);
};
return AppClass;
});
@markhealey
Copy link

@montlebalm, it's late but I wanted to comment on just part of this now. I like the simplicity of the AppClass. A couple questions:

  1. Do you envision the App Developer owns the F2.BaseAppClass? Or is that something provided by F2.js, perhaps partially?
  2. It appears you've removed the AppConfig from the AppClass constructor and are only passing Context through as the 3rd arg—is that accurate?

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment