In a jsviews based app, I have a data object that contains a type attribute (actually a server type).
I'd like to convert it and append a suffix to pass to a tmpl inclusion.
Let's say I have :
$.views.converters({
"serverSideTypeToLocalType": function(serverSideType) {
switch(serverSideType) {
case "server-side-type1":
return "type1";
case "server-side-type2":
return "type2";
case "server-side-type3":
return "type3";
default:
throw "Invalid type";
}
}
});
I also have templates :
<script type="text/x-jsrender" id"type1-edit">
template for editing type 1
</script>
<script type="text/x-jsrender" id"type1-view">
template for viewing type 1
</script><script type="text/x-jsrender" id"type2-edit">
template for editing type 2
</script>
<script type="text/x-jsrender" id"type2-view">
template for viewing type 2
</script><script type="text/x-jsrender" id"type3-edit">
template for editing type 3
</script>
<script type="text/x-jsrender" id"type3-view">
template for viewing type 3
</script>
My data object is :
var data = { MyObjects : [
{
"ServerSideType": "server-side-type1",
"IsEditing" : true
},{
"ServerSideType": "server-side-type2",
"IsEditing" : false
}] };
How to construct a main template that includes dynamically the correct template based on ServerSideType
and IsEditing
properties ?
I tried :
<div>
{^{for MyObjects}}
{^{include ^tmpl=({serverSideTypeToLocalType:ServerSideType}+ "-" + IsEditing ? "edit":"view")/}}
{{/for}}
</div>
but it fails with a weird error Cannot read property 'bd' of undefined
.
Here is a reproductible sample:
(function($) {
$(function() {
$.views.converters({
"serverSideTypeToLocalType": function(serverSideType) {
switch (serverSideType) {
case "server-side-type1":
return "type1";
case "server-side-type2":
return "type2";
case "server-side-type3":
return "type3";
default:
throw "Invalid type";
}
}
});
var data = {
MyObjects: [{
"ServerSideType": "server-side-type1",
"IsEditing": true
}, {
"ServerSideType": "server-side-type2",
"IsEditing": false
}]
};
var tmpl = $.templates("#main");
tmpl.link("#container", data);
});
})(jQuery);
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jsviews/0.9.90/jsviews.min.js"></script>
<script type="text/x-jsrender" id="main">
<div>
{^{for MyObjects}}
<p>Object n° {^{:#index +1}}</p>
{^{include ^tmpl=({serverSideTypeToLocalType:ServerSideType}+ "-" + IsEditing ? "edit":"view")/}}
{{/for}}
</div>
</script>
<script type="text/x-jsrender" id="type1-edit">
<div>
template for editing type 1
</div>
</script>
<script type="text/x-jsrender" id="type1-view">
<div>
template for viewing type 1
</div>
</script>
<script type="text/x-jsrender" id="type2-edit">
<div>
template for editing type 2
</div>
</script>
<script type="text/x-jsrender" id="type2-view">
<div>
template for viewing type 2
</div>
</script>
<script type="text/x-jsrender" id="type3-edit">
<div>
template for editing type 3
</div>
</script>
<script type="text/x-jsrender" id="type3-view">
<div>
template for viewing type 3
</div>
</script>
<div id="container">Loading ...</div>
You can't nest a {:...}
tag within the markup of a {{...}}
tag.
I would suggest using a helper, rather than a converter:
{^{include ^tmpl="#" + ~serverToLocal(ServerSideType) + "-" + (IsEditing ? "edit":"view")/}}
You can also use a data-linked element:
<span data-link='{include ^tmpl="#" + ~serverToLocal(ServerSideType)+ "-" + (IsEditing ? "edit" : "view")}'></span>
(function($) {
$(function() {
function serverToLocal(serverSideType) {
switch (serverSideType) {
case "server-side-type1":
return "type1";
case "server-side-type2":
return "type2";
case "server-side-type3":
return "type3";
default:
throw "Invalid type";
}
}
var data = {
MyObjects: [{
"ServerSideType": "server-side-type1",
"IsEditing": true
}, {
"ServerSideType": "server-side-type2",
"IsEditing": false
}]
};
var tmpl = $.templates("#main");
tmpl.link("#container", data, {serverToLocal: serverToLocal});
});
})(jQuery);
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jsviews/0.9.90/jsviews.min.js"></script>
<script type="text/x-jsrender" id="main">
<div>
{^{for MyObjects}}
<p>Object n° {^{:#index +1}}</p>
<input data-link="ServerSideType" />
<input data-link="IsEditing" type="checkbox"/>
{^{include ^tmpl="#" + ~serverToLocal(ServerSideType) + "-" + (IsEditing ? "edit":"view")/}}
{{/for}}
</div>
Two:
<div>
{^{for MyObjects}}
<p>Object n° {^{:#index +1}}</p>
<span data-link='{include ^tmpl="#" + ~serverToLocal(ServerSideType)+ "-" + (IsEditing ? "edit" : "view")}'></span>
{{/for}}
</div>
</script>
<script type="text/x-jsrender" id="type1-edit">
<div>
template for editing type 1
</div>
</script>
<script type="text/x-jsrender" id="type1-view">
<div>
template for viewing type 1
</div>
</script>
<script type="text/x-jsrender" id="type2-edit">
<div>
template for editing type 2
</div>
</script>
<script type="text/x-jsrender" id="type2-view">
<div>
template for viewing type 2
</div>
</script>
<script type="text/x-jsrender" id="type3-edit">
<div>
template for editing type 3
</div>
</script>
<script type="text/x-jsrender" id="type3-view">
<div>
template for viewing type 3
</div>
</script>
<div id="container">Loading ...</div>