Tomek Buszewski
Tomek Buszewski

Reputation: 7955

Angular components accessing its controller

I'm trying to get my head around Angular 1 components. I wrote simple component that would have set a background colour on init and then would have the colour changed with the button click.

Here's the code:

<shadow colour="black"></shadow>

app.component('shadow', {
    bindings: {
        colour: '='
    },
    controller: function() {
        function setColour(col) {
            this.colour = col;
        }
    },
    scope: {},
    template: ['<div ',
        'style="background: {{ shadow.colour }}; width: 100px; height: 100px;">',
        '<button ng-click="shadow.setColour(red)">Button</button>',
    '</div>'].join('')
});

Unfortunately, it doesn't work. From what I've read, when no controllerAs is passed, Angular will assume that components name is the controller name. So I did try to write it that way. Where did I go wrong?

Upvotes: 0

Views: 63

Answers (2)

Prashant
Prashant

Reputation: 8050

Angular automatically uses the name '$ctrl' if no controllerAs is passed. From angular source:

controllerAs: identifierForController(options.controller) || options.controllerAs || '$ctrl',

EDIT 1:

  1. Also, the binding should be '@' instead of '='.
  2. You have never set the function "setColour" to the controller itself.

EDIT 2:

The corrected code would be something like this:

app.component('shadow', {
    bindings: {
        colour: '@'
    },
    controller: function() {
        this.colourSecondary = 'red';

        this.setColour = setColour;

        function setColour(colour) {
            this.colour = colour;
        }
    },
    scope: {},
    template: ['<div ',
        'style="background: {{ $ctrl.colour }}; width: 100px; height: 100px;">',
        '<button ng-click="$ctrl.setColour($ctrl.colourSecondary);">Button</button>',
        '</div>'].join('')
});

Bindings with '@' take either string or interpolated variables e.g. {{ colour }}.

With '=', angular expects a scope variable with the name 'colour' which is not present.

Upvotes: 1

DamianoPantani
DamianoPantani

Reputation: 1386

I'd do it like so:

angular
    .module('yourModule')
    .directive('shadow', shadow);

function shadow() {
    return {
        scope: {
            colour: '=?'
        },
        restrict: 'AE',
        template: '<div style="background: {{colour}}; width: 100px; height: 100px;"></div>'
    };
}

In html:

<button ng-click="setColor('red')">Button</button>
<shadow color="{{yourColor}}"></button>

and in your main directive:

$scope.setColor = function(newColor){
    $scope.yourColor = newColor;
}

Upvotes: 0

Related Questions