简体   繁体   中英

Call function on html page from controller in AngularJS

Long story short:

I have the following file structure:

class RandomCtrl {
    constructor(randomService) {
    this.randomService = randomService;
    ...
    }

    $onInit() {
        getData.call(null, this);
    }

    ...

    }

    updateLegendChart(){
         RandomCtrl.chartStuff.chart.unload("ID-1234");
    }

    function getData(RandomCtrl) {

        RandomCtrl.ChartDataService.getData(DemandCtrl.dataParams).then(result => {
        RandomCtrl.result = result.data;
        RandomCtrl.siteNames = result.data.map(element => element.SiteName);
        RandomCtrl.keys = Object.keys(result.data);
        RandomCtrl.chartStuff = getChart(result.data);  
        RandomCtrl.chartStuff.chart.unload("ID-1234");   ////<-HERE IT WORKS!!!

    }).catch((e) => {
        console.log(e);
    });
    }


    function getChart(data) {
        const chartOptions = getWeekHourlyOptions(data);

        const allCols = [].concat(chartOptions.dataColumns);

        ...
        return {allCols, chart};
    }

    ...

    RandomCtrl.$inject = ['randomService'];

    export const Random = {
        bindings: {
            data: '<',
            siteNames: '<'
        },
        templateUrl: randomPageHtml,
        controller: RandomCtrl
    };

I have a chart containing multiple lines each of them representing a site, I want to remove or add them when I click on their name in a legend section.

I do this by using load and unload methods of Billboard.js .

If a write it inside getData() , the line with HERE IT WORKS , it works but it does it every time I run the code, I want to do it only when I click a button.

The problem is that I cannot glue this functionality to an ng-click into an html page.

This is the html page:

<div class="demand page">
    <div  class="chart-legend-container">
        <div ng-repeat="site in $ctrl.keys">
            <chart-legend site="$ctrl.siteNames[site]" keys= "$ctrl.keys"></chart-legend>
            <button ng-click="$ctrl.updateLegendChart()">CLICK ME</button>
        </div>
    <div>
</div>

My approach was to use updateLegendChart() which is a method on the controller which should be called when ng-click is triggered.

The method is in the controller and looks like this:

updateLegendChart(){
    RandomCtrl.chartStuff.chart.unload("ID-1234");
}

The error says:

TypeError: Cannot read property 'chart' of undefined

Any idea how to call that function properly?

Inside $onInit hook 'this' keyword refers to the $onInit context , not to RandomCtrl

$onInit() {
    getData.call(null, this);
}

Probably something you don't want to do, because then you're appending all those properties (result, chartStuff, etc.) to the wrong object.

..
//here RandomCtrl is still $onInit context, and not the the class context
RandomCtrl.chartStuff = getChart(result.data);  

As a consequence when you invoke updateLegendChart() , RandomCtrl doesn't have any chartStuff field, thus you get the exception "TypeError: Cannot read property 'chart' of undefined"

updateLegendChart(){
   RandomCtrl.chartStuff.chart.unload("ID-1234");
}

if you try passing RandomCtrl directly you should be fine.

$onInit() {
    getData.call(null, RandomCtrl);
}

To make it work as expected it should be replaced RandomCtrl with this inside updateLegendChart() method like this:

updateLegendChart(siteNames){

    this.chartStuff.chart.unload(siteNames);
}

It doesn't need to modify $onInit() method, it should be let as it is

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM