Reputation: 18258
JSfiddle : http://jsfiddle.net/hugolpz2/QCjJD/9/
Given an html anchors with hard coded buttons, purely JS injected buttons, and Mustache injected buttons, with end result such:
<div id="anchor">
<button class="tpl html status0" data-lexeme="A">A</button>
<button class="tpl html status0" data-lexeme="B">B</button>
<button class="tpl PureJS status0" data-lexeme="A"></button><!-- injected with pure JS -->
<button class="tpl PureJS status0" data-lexeme="B">B</button><!-- injected with pure JS -->
<button class="tpl Mustache status0" data-lexeme="A">A</button><!-- injected with Mustache -->
<button class="tpl Mustache status0" data-lexeme="B">B</button><!-- injected with Mustache -->
</div>
Given the referential data such
var json = [
{ "id": "A", "status": 0 },
{ "id": "B", "status": 0 },
{ "id": "C", "status": 1 },
{ "id": "AB", "status": 1 },
{ "id": "ABC", "status": 1 },
// { ... } +100 entries
];
Given the JS/JQuery function classUpdateFromData() which bpdate buttons' class from data.
// classUpdateFromData():
function classUpdateFromData($set) {
$($set).each(function (i) { // <------------------------------ seems this is the trouble! Select html, js,but NOT mustache generated content!
var lexeme = $(this).data('lexeme');
var val = getJsonVal(json, lexeme);
if (val.status === 1) {
$(this).toggleClass('status1 status0');
} else { /* nothing yet! */ }
});
}
classUpdateFromData('#anchor > .tpl');
Why my function only update hard coded buttons and purely JS injected buttons and NOT MustacheJS injected buttons ?
How to fix make it works on them all, including Mustache created function ?
Note: classUpdateFromData() is fired AFTER the templates function.
Upvotes: 1
Views: 87
Reputation: 262939
Your injectTPL()
function is asynchronous: it actually returns before the JSON data is fetched and the templates are rendered.
Look at the call to $.getJSON(): it takes a callback function and invokes it when the data becomes ready. That function, in turn, renders the templates and appends the resulting markup to the document.
Since classUpdateFromData()
is called right after injectTPL()
, it runs before that callback function is invoked.
You can either invoke classUpdateFromData()
from the callback passed to $.getJSON()
or, more generically, refactor injectTPL()
so it takes a callback itself and invokes it from the callback passed to $.getJSON()
:
function injectTPL(url, list, tplId, anchor, callback) {
console.log("Mustache TPL = Fired !");
$.getJSON(url, function(data) {
for (var i = 0; i < list.length; i++) {
var lexeme = list[i]; // "火山口";
var template = '{{#CFDICT}}{{#'+ lexeme +'}}' + $(tplId).html()
+ '{{/'+ lexeme +'}}{{/CFDICT}}';
var info = Mustache.to_html(template, data);
$(anchor).append(info);
}
callback(); // Invoke our own callback.
});
console.log("Mustache TPL = End !");
}
You can then invoke classUpdateFromData()
from the callback you pass to injectTPL()
, and it will be called at the right time:
injectTPL(
'http://d.codio.com/hugolpz/getJson--/App/data/cfdict.json',
l, '#CFDICT-tpl', '#anchor', function() {
classUpdateFromData('#anchor > .tpl');
}
);
You will find an updated fiddle here.
Upvotes: 3