To run:
- Clone this gist
bower install
- Serve index.html
- Open developer tools inspector
- First
<li>
element has 4 widget instances attached; second had 3, etc.
"use strict"; | |
require.config({ | |
"baseUrl" : "bower_components", | |
"packages" : [ | |
{ | |
name : "jquery", | |
main : "dist/jquery.js" | |
}, | |
{ | |
name : "requirejs", | |
main : "require.js" | |
}, | |
{ | |
name : "when", | |
main : "when.js" | |
}, | |
{ | |
name : "troopbug", | |
location : "../" | |
} | |
], | |
"map" : { | |
"*" : { | |
"template" : "mu-template/plugin", | |
"text" : "requirejs-text/text" | |
} | |
}, | |
"deps" : ["require", "jquery"], | |
"callback" : function Boot(contextRequire, jQuery) { | |
contextRequire([ | |
"troopjs-dom/application/widget", | |
"troopjs-dom/hash/widget", | |
"troopjs-dom/loom/plugin" | |
], function Strap(Application, RouteWidget) { | |
jQuery(function ($) { | |
Application($("html"), "bootstrap", RouteWidget($(window))).start(); | |
}); | |
}); | |
} | |
}); |
{ | |
"name": "troopbug", | |
"version": "0.0.0", | |
"authors": [ | |
"Eyal Arubas <[email protected]>" | |
], | |
"moduleType": [ | |
"amd" | |
], | |
"license": "MIT", | |
"private": true, | |
"ignore": [ | |
"**/.*", | |
"node_modules", | |
"bower_components", | |
"test", | |
"tests" | |
], | |
"dependencies": { | |
"troopjs": "develop", | |
"requirejs": "~2.1.15", | |
"requirejs-text": "~2.0.12", | |
"when": "~3.4.6", | |
"mu-template": "~1.0.5", | |
"jquery": "~2.1.1" | |
} | |
} |
<!doctype html> | |
<html lang="en" data-framework="troopjs"> | |
<body> | |
<ul data-weave="troopbug/list"></ul> | |
<script src="bower_components/requirejs/require.js"></script> | |
<script src="app.js"></script> | |
</body> | |
</html> |
<li data-weave="troopbug/item(<%= data.id %>)"> | |
<%= data.id %> | |
</li> |
define([ "troopjs-dom/component/widget", "poly/array" ], | |
function Item(Widget) { | |
return Widget.extend(); | |
} | |
); |
define([ | |
"troopjs-dom/component/widget", | |
"template!./item.html", | |
"when" | |
], | |
function List(Widget, template, when) { | |
"use strict"; | |
var items = [ {id:0}, {id:1}, {id:2}, {id:3} ]; | |
return Widget.extend({ | |
"sig/start": function start() { | |
var me = this; | |
return when.map(items, function (item) { | |
return me.append(template, item); | |
}); | |
}, | |
}); | |
} | |
); |
So initial findings is that the weave is not entirely safe for concurrent execution. See, the result of a weave is a promise that will resolve once the weaving is completed, but what happens when someone calls weave on the same (or a parent) element while the weave is still resolving? Well, it will weave multiple times, like it does now. The reason for this is that we don't remove or rename the
data-weave
attribute early enough in the async call (actually, this should probably be done sync before we start creating the promise)