I have an html string that i build dynamically in my Component's controller. This way :
let strDl = this.domainsLabel.split('>');
angular.forEach(strDl, (element, index) => {
if (index < strDl.length - 1)
this.domainsLabelHtml += `<a position="${index}" ng-click="TabsDomains.goTo($event.target)">${element}</a>>`;
else
this.domainsLabelHtml += `${element}`;
});
if (this.domainsLabelHtml.endsWith('>'))
this.domainsLabelHtml = this.domainsLabelHtml.slice(0, -5);
The html code :
<span ng-bind-html="TabsDomains.trustedHtml(TabsDomains.domainsLabelHtml)"></span>
I get the following result :
But nothing happens when I click. Since nothing worked, i wrote an html content manually, like this :
<span><a position="0" ng-click="TabsDomains.goTo($event.target)">TEST</a>blabla</span>
And i get the following result generated staticCode:
Which works perfectly.
Since the two chunks of code look exactly the same to me, I don't understand why the dynamically generated isn't working and the static one does.
Here is the code of the trusted html :
public trustedHtml = function (plainText) {
return this.$sce.trustAsHtml(plainText);
}
My class looks like this :
/// <reference path='tabs.d.ts'/>
module rundeckManager.tabs {
'use strict';
class TabsDomainsComponentController implements ITabsDomainsComponentController {
static $inject = ['$filter', '$state','$rootScope','jobService','$sce','$compile','$scope'];
public test = false;
public domainsLabel: any;
public jobsLabel: any;
public domains: any;
public jobs: any;
//Previous domains and jobs of the hierarchy
//So we always keep the data, no need to reprocess it
public pDomains: any;
public ppDomains: any;
public pppDomains: any;
public pJobs: any;
public ppJobs: any;
public pppJobs: any;
public pFolder: any;
public ppFolder: any;
public pppFolder: any;
public firstBack: any;
public jobDetails: jobs.IJobDetails;
public idJob: string;
public showJobDetails: boolean;
public showLoadingBar: boolean;
public domainsLabelHtml: any;
constructor(public $filter: any, public $state: any, public $rootScope: any, public jobService: jobs.IJobService, public $sce: any, public $compile: any, public $scope: ng.IScope) {
this.firstBack = $rootScope.back;
this.showJobDetails = false;
this.showLoadingBar = false;
this.domainsLabelHtml = ``;
}
public $onChanges(changes) {
if (changes.domains) {
this.domains = changes.domains.currentValue;
}
if (changes.jobs) {
this.jobs = changes.jobs.currentValue;
}
if (changes.domainsLabel) {
this.domainsLabel = changes.domainsLabel.currentValue;
let strDl = this.domainsLabel.split('>');
angular.forEach(strDl, (element, index) => {
if (index < strDl.length - 1)
this.domainsLabelHtml += `<a position="${index}" ng-click="TabsDomains.goTo($event.target)">${element}</a>>`;
else
this.domainsLabelHtml += `${element}`;
});
if (this.domainsLabelHtml.endsWith('>'))
this.domainsLabelHtml = this.domainsLabelHtml.slice(0, -5);
this.$compile(document.querySelector('#id-of-span'))(this.$scope);
}
if (changes.jobsLabel) {
this.jobsLabel = changes.jobsLabel.currentValue;
}
}
public trustedHtml(plainText: string) {
return this.$sce.trustAsHtml(plainText);
}
public goToDetails(id: string) {
this.idJob = id;
//console.log(id);
this.showLoadingBar = true;
this.jobService.getJobDetails(id).then((data) => {
this.jobDetails = data.data.job;
this.showJobDetails = true;
this.showLoadingBar = false;
});
this.$rootScope.back = () => {
this.showJobDetails = false;
this.showLoadingBar = false;
this.$rootScope.back = this.firstBack;
};
}
public goTo(element:any) {
let position = element.attributes['position'].value;
let strDomains = this.domainsLabel.split('>');
console.log('its working');
}
public redirectTo(name: string) {
switch (this.$state.current.name) {
case 'root.domains':
var proj = this.$filter('filter')(this.domains, { id: name }, true);
var subDomainsParam = proj[0].subDomains;
var jobsParam = proj[0].jobs;
var obj = {
subDomName: this.domainsLabel + '>' + name,
pDomains: this.domains,
subDomains: subDomainsParam,
jobs: jobsParam,
pJobs: this.jobs,
pFolder: this.domainsLabel
};
this.$state.go('root.subDomains', obj);
break;
case 'root.subDomains':
var proj = this.$filter('filter')(this.domains, { id: name }, true);
var subSubDomainsParam = proj[0].subSubDomains;
var jobsParam = proj[0].jobs;
var obj2 = {
subSubDomName: this.domainsLabel + '>' + name,
pDomains: this.domains,
ppDomains: this.pDomains,
subSubDomains: subSubDomainsParam,
jobs: jobsParam,
pJobs: this.jobs,
ppJobs: this.pJobs,
pFolder: this.domainsLabel,
ppFolder: this.pFolder
};
this.$state.go('root.subSubDomains', obj2);
break;
case 'root.subSubDomains':
var proj = this.$filter('filter')(this.domains, { id: name }, true);
var jobsParam = proj[0].jobs;
var obj1 = {
lastLevelName: this.domainsLabel + '>' + name,
pDomains: this.domains,
ppDomains: this.pDomains,
pppDomains: this.ppDomains,
jobs: jobsParam,
pJobs: this.jobs,
ppJobs: this.pJobs,
pFolder: this.domainsLabel,
ppFolder: this.pFolder,
pppFolder: this.ppFolder
};
this.$state.go('root.lastLevel', obj1);
break;
}
}
}
class TabsDomainsComponent implements ng.IComponentOptions {
public bindings: any;
public controller: any;
public controllerAs: string;
public templateUrl: string;
constructor() {
this.bindings = {
domains: '<',
jobs: '<',
jobsLabel: '<',
domainsLabel: '<',
pDomains: '<',
ppDomains: '<',
pppDomains: '<',
pJobs: '<',
ppJobs: '<',
pppJobs: '<',
pFolder: '<',
ppFolder: '<',
pppFolder: '<'
};
this.controller = TabsDomainsComponentController;
this.controllerAs = 'TabsDomains';
this.templateUrl = 'public/app/views/components/tabsDomains/tabs.domains.html';
}
}
angular.module('rundeckManager.tabs')
.component('tabsDomains', new TabsDomainsComponent());
}
I found an answer which looked like the problem I'm having at first, but the solution didn't apply to my case :
Links not working in ng-bind-html
I'd be great if anyone can explain it to me and help me with a solution.
Thank you
You have to run $compile(this.domainsLabelHtml)($scope);
after you inject Html code, that should be managed by Angular.
EDIT
I think compiling this.domainsLabelHtml might not work. Try to add an Id to than span that should bind the Html and than do:
//Html
<span id="id-of-span" ng-bind-html="TabsDomains.trustedHtml(TabsDomains.domainsLabelHtml)"></span>
//JS
$compile(angular.element('#id-of-span'))($scope);