TypeScript + AngularJS :无法与 ng-bind-html 生成的 html 交互

TypeScript + AngularJS : Can't interact with the html generated by ng-bind-html

我有一个 html 字符串,它是我在组件的控制器中动态构建的。这样:

    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>&#62;`;
                else
                    this.domainsLabelHtml += `${element}`;
            });
            if (this.domainsLabelHtml.endsWith('&#62;'))
                this.domainsLabelHtml = this.domainsLabelHtml.slice(0, -5);

html代码:

    <span ng-bind-html="TabsDomains.trustedHtml(TabsDomains.domainsLabelHtml)"></span>

我得到以下结果:

dynamicallyGeneratedCode

但是当我点击时没有任何反应。 由于没有任何效果,我手动写了一个 html 内容,如下所示:

    <span><a position="0" ng-click="TabsDomains.goTo($event.target)">TEST</a>blabla</span>

我生成了以下结果 staticCode:

效果很好。

由于这两段代码在我看来完全一样,所以我不明白为什么动态生成的代码不起作用而静态代码却起作用。

这是受信任的 html 的代码:

     public trustedHtml = function (plainText) {
        return this.$sce.trustAsHtml(plainText);
    }

我的 class 看起来像这样:

    /// <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>&#62;`;
                else
                    this.domainsLabelHtml += `${element}`;
            });
            if (this.domainsLabelHtml.endsWith('&#62;'))
                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());

    }

我找到了一个看起来像我最初遇到的问题的答案,但该解决方案不适用于我的情况:

Links not working in ng-bind-html

如果有人能向我解释并帮助我解决问题,我会很高兴。

谢谢

在注入 Html 代码后,您必须 运行 $compile(this.domainsLabelHtml)($scope);,这应该由 Angular 管理。

编辑

我认为编译 this.domainsLabelHtml 可能行不通。尝试向应该绑定 Html 的跨度添加一个 Id 而不是:

//Html
 <span id="id-of-span" ng-bind-html="TabsDomains.trustedHtml(TabsDomains.domainsLabelHtml)"></span>

//JS
$compile(angular.element('#id-of-span'))($scope);