0

I have the following simple controller which using a directive/component and passing a function as binding.

When the function being called I don't have reference to use any of the controller class services.

In this case in my controller public onTileClicked function I don't have access to tileService

Controller js:

namespace app.dashboard {
    'use strict';

    export class DashboardController {
        static $inject:Array<string> = ['$q', 'logger', 'tileService'];

        constructor(private $q:ng.IQService,
                    private tileService:TileService) {
        }

        public tiles:Array<ITile> = [];

        public onTileClicked(tile:ITile) {                
            this.tileService.getTiles(tile.ID) // No access to tileService
                .then((data)=> {
                    this.tiles = data; // Won't have access to this.tiles
                })
        }
    }

    angular
        .module('app.dashboard')
        .controller('DashboardController', DashboardController);
}

Controller html:

<div class="tiles-container">
    <tile-component ng-repeat="tile in DashboardCtrl.tiles" tile="tile"
                    on-tile-clicked="DashboardCtrl.onTileClicked">
    </tile-component>
</div>

Directive js:

class TileComponent {
    tile:ITile;
    onTileClicked:Function;

    /* @ngInject */
    constructor() {
    }

    tileClicked() {
        this.onTileClicked()(this.tile);
    }
}

angular.module('app.dashboard')
.component('tileComponent', {
    templateUrl: 'app/dashboard/directives/tile.html',
    controller: TileComponent,
    controllerAs: 'tileCtrl',
    bindings: {
        tile: '<',
        onTileClicked: "&"
    }
});

onTileClicked js:

DashboardController.prototype.onTileClicked = function (tile) {
    var _this = this;
    this.tileService.getTiles(tile.ID)
        .then(function (tiles) {
        _this.tiles = tiles;
    });
};
georgeawg
  • 48,608
  • 13
  • 72
  • 95
Dor Cohen
  • 16,769
  • 23
  • 93
  • 161

1 Answers1

2

Your binding (in html) to the function is wrong. You missed the parenthesis :

<tile-component ng-repeat="tile in DashboardCtrl.tiles" tile="tile"
                on-tile-clicked="DashboardCtrl.onTileClicked()"> <!-- HERE -->
</tile-component>
t.ouvre
  • 2,856
  • 1
  • 11
  • 17
  • Thanks, it helped when I added on-tile-clicked="DashboardCtrl.onTileClicked(tile)" – Dor Cohen Feb 18 '16 at 15:07
  • But now I can't access the this inside the promise: this.tiles = data; Can you help? – Dor Cohen Feb 18 '16 at 15:07
  • if you use a lambda style function, this refers to your DashboardController instance. Can you confirm you use the lamdba style ? If yes, can you test your function with this code : public onTileClicked(tile:ITile) { var self = this; this.tileService.getTiles(tile.ID) // No access to tileService .then((data)=> { self.tiles = data; // Won't have access to this.tiles }) } – t.ouvre Feb 18 '16 at 15:12
  • It's working but it's so ugly, there is no other way? – Dor Cohen Feb 18 '16 at 15:19
  • I don't understand why your this reference is bad in your lambda function... can you post the generated JavaScript code of the function ? – t.ouvre Feb 18 '16 at 15:20
  • I've added onTileClicked js to the end of my question, it seems it's does exactly what I did but it's not working unless I'm using the code from comment – Dor Cohen Feb 18 '16 at 15:23
  • ok, it seems good... can you post the code of the getTiles method please ? – t.ouvre Feb 18 '16 at 15:49
  • It seems like it's working, the problem is that on Chrome developer tools this resolved to undefined when you debug the typescript file – Dor Cohen Feb 18 '16 at 16:29
  • 1
    ooh yes ! I understand :) when you use a debugger (in chrome, safari, IE, edge...), you a use a JavaScript debugger (even if you see your typescript code). So the "this" keywork in typescript of a lambda function is not the same "this" of the JavaScript. If you want the value of "this" keyword when you debug a typescript lamdba function, you have to look the JavaScript "_this" variable. – t.ouvre Feb 18 '16 at 16:51
  • Can you assist in a similar problem I have? I tried your suggest approach but I have some issues - http://stackoverflow.com/questions/35537766/cant-access-controller-scope-from-angular-component-output-function-using-type – Dor Cohen Feb 21 '16 at 15:13