Skip to content

Instantly share code, notes, and snippets.

@montlebalm
Last active December 23, 2015 18:39
Show Gist options
  • Save montlebalm/6677612 to your computer and use it in GitHub Desktop.
Save montlebalm/6677612 to your computer and use it in GitHub Desktop.
An example of loading an F2 app with real AMD.
// AppClass
define("com_markit_header", ["F2.Defer", "F2", "MyCoolClass"], function(defer, F2) {
var AppClass = function() {};
return AppClass;
});
// Container
require.config({
paths: {
"jquery-2.1.0": "http://123/",
"F2.CoolPlugin": "..."
}
});
require(["F2", "F2.CoolPlugin"], function(F2, plugin) {
F2.config({
loadScripts: function(paths, inlines, cb) {
// load scripts
// load inlines
cb();
},
loadStyles: function(paths) {
paths = paths.select(function(path) {
return "css!" + path;
})
require(paths);
}
});
// F2.load() returns a promise object that's fired when all have been loaded
F2.load([
{ appId: "com_markit_header", manifestUrl: "http://markit.com/f2/apps" }
]).then(function(header) {
console.log(header.instanceId);
// Add the html to the page
$("div.header").append(header.root);
});
});
// F2 Codebase
// Define "Defer"
// Defer wraps the $q promise library
define("F2.Defer", ["$q"], function($q) {
return $q;
});
define("F2", ["F2.Defer"], function(defer) {
return {
loadScripts: function(paths, inlines, callback) { /* ... */ },
loadStyles: function(paths) { /* ... */ },
guid: function() { /* ... */ },
// ...
load: function(appConfigs) {
var self = this;
var deferred = defer.deferred();
var appsByUrl = {};
var numUrlsToRequest = 0;
// Get an obj of appIds keyed by manifestUrl
for (var i = 0; i < appConfigs.length; i++) {
if (!appsByUrl[appConfigs[i].manifestUrl]) {
appsByUrl[appConfigs[i].manifestUrl] = [];
numUrlsToRequest += 1;
}
appsByUrl[appConfigs[i].manifestUrl].push(appIds[i]);
}
// Obj that holds all the xhr responses
var combinedResponses = {
scripts: [],
styles: [],
inlineScripts: [],
apps: []
};
// Request all apps from each url
for (var url in appsByUrl) {
$.ajax({
url: url,
type: "post",
data: {
params: JSON.stringify(appsByUrl[url])
},
success: function(response) {
// Combine the responses
combinedResponses.scripts = combinedResponses.scripts.concat(response.scripts || []);
combinedResponses.styles = combinedResponses.styles.concat(response.styles || []);
combinedResponses.inlineScripts = combinedResponses.inlineScripts.concat(response.inlineScripts || []);
combinedResponses.apps = combinedResponses.apps.concat(response.apps) || [];
// See if we've finished requesting all the apps
if (--numUrlsToRequest == 0) {
self.loadStyles(combinedResponses.styles);
self.loadScripts(combinedResponses.scripts, combinedResponses.inlineScripts, function() {
self.loadApps(combinedResponses.apps);
});
}
}
});
}
return deferred.promise;
},
loadApps: function(apps) {
var self = this;
var appIds = apps.select("appId");
// Wrap in Define()
// App classes should be wrapped in "define()", so this will load them
require(appIds, function(/* appClass1, appClass2 */) {
var appClasses = Array.prototype.slice(arguments, appIds.length);
var deferArgs = {};
for (var i = 0; i < apps.length; i++) {
// Create a new element and add the app html
// This will allow us to easily extract a DOM node from the markup
var rootParent = document.createElement("div");
rootParent.innerHTML = apps[i].html;
deferArgs[apps[i].appId] = {
instanceId: self.guid(),
root: rootParent.firstChild
};
}
// Allow the container to act on the loaded apps
deferred.resolve(deferArgs);
// Instantiate the app classes
for (var i = 0; i < appIds.length; i++) {
var instanceId = deferArgs[appIds[i]].instanceId;
var root = deferArgs[appIds[i]].root;
// Finally, create an instance of the appClass
new appClasses[i](root, instanceId).init();
}
});
}
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment