Skip to content

Instantly share code, notes, and snippets.

@EyalAr
Last active August 29, 2015 14:06
Show Gist options
  • Save EyalAr/c8d00f28f287567422d5 to your computer and use it in GitHub Desktop.
Save EyalAr/c8d00f28f287567422d5 to your computer and use it in GitHub Desktop.
TroopJS data-weave inside template bug - multiple widget instances are created for elements

To run:

  1. Clone this gist
  2. bower install
  3. Serve index.html
  4. Open developer tools inspector
  5. 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);
});
},
});
}
);
@mikaelkaron
Copy link

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)

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