I have been trying to get a dynamic behavior from a composition of directives. Here is the code I am using for sampler.js and index.html:
"use strict";
var app = angular.module("myApp", []);
var Sampler = (function () {
function Sampler(sampler) {
this.sampler = sampler;
this.name = null;
this.value = null;
if (sampler) {
this.name = sampler.name;
this.value = sampler.value;
}
}
Sampler.prototype.getTemplateFor = function (file) {
return 'templates/' + name + '/' + file + '.html';
};
Sampler.prototype.addA = function () {
this.value = 'A';
};
Sampler.prototype.addB = function () {
this.value = 'B';
};
Sampler.create = function (name) {
var samplerClass = name + 'Sampler';
var items = samplerClass.split('.');
var creator = (window || this);
for (var i = 0; i < items.length; i++) {
creator = creator[items[i]];
}
if (typeof creator !== 'function') {
throw new Error('Class named ' + samplerClass + ' not found.');
}
var sampler = new creator({
name: name
});
if (!(sampler instanceof Sampler)) {
throw new Error(name + ' is not instance of Sampler.');
}
return sampler;
};
return Sampler;
}());
app.directive("sampler", function ($compile) {
return {
restrict: "E",
scope: { result: '=' },
link: function (scope, element, attributes) {
var name = !attributes.name ? '' : attributes.name;
var sampler = Sampler.create(name);
scope.sampler = sampler;
var template = '<div class="sampler form-horizontal">' +
' <sampler-item ng-if="!!sampler.value" sampler="sampler" />' +
' <sampler-new ng-if="!sampler.value" sampler="sampler" />' +
'</div>';
if (name) {
$.ajax({
async: false,
url: sampler.getTemplateFor('sampler'),
success: function (response) { template = response; },
});
}
var content = $compile(template)(scope);
element.replaceWith(content);
scope.$watch('sampler.value', function () {
scope.result = scope.sampler.value;
});
}
};
});
app.directive("samplerNew", function ($compile) {
return {
restrict: "E",
scope: { sampler: '=' },
link: function (scope, element) {
var sampler = scope.sampler;
var template = '\
<div class="new">\
<button type="button" class="btn btn-default" ng-click="sampler.addA()">Add A</button>\
<button type="button" class="btn btn-default" ng-click="sampler.addB()">Add B</button>\
</div>';
if (sampler.name) {
$.ajax({
async: false,
url: sampler.getTemplateFor('new'),
success: function (response) { template = response; },
});
}
var content = $compile(template)(scope);
element.replaceWith(content);
}
};
});
app.directive("samplerItem", function ($compile) {
return {
restrict: "E",
scope: { sampler: '=' },
link: function (scope, element) {
var sampler = scope.sampler;
var template = '\
<div class="item">\
Item: {{sampler.value}}\
</div>';
if (sampler.name) {
$.ajax({
async: false,
url: sampler.getTemplateFor('sampler'),
success: function (response) { template = response; },
});
}
var content = $compile(template)(scope);
element.replaceWith(content);
}
};
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>TypeScript HTML App</title>
</head>
<body ng-app="myApp">
<sampler result="result"></sampler>
Expression: {{result}}
<script src="lib/jquery/jquery-3.1.1.js"></script>
<script src="lib/angular/js/angular.js"></script>
<script src="js/directives/sampler.js"></script>
</body>
</html>
When the page loads the output is:
After you press a button the expected result should be:
But the result is:
Please note that I am using link to load the template because I need to load a dynamic template with fallback to a default one.
Thinks works fine if I use the template property of the directive but that does not suits me because of the dynamic template so please do not send this as an answer.
Can anyone help me on that? Thanks