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-weaveattribute early enough in the async call (actually, this should probably be done sync before we start creating the promise)