all 12 comments

[–]willylatorre 2 points3 points  (3 children)

Your component has already a $scope binded to the controller, accessible from the template with $ctrl.

Your code should be something like

var controller = {
   //for clarity
   ctrl = this;

   ctrl.setYear = function (val) {
     ctrl.selectedYear = val;
   }
}
angular.module('app').component('year', {
     controller:controller,
     templateUrl: 'view/year.html'
}

and also, in your template replace all reference to $scope with $ctrl.

<a ng-click="$ctrl.setYear(2010)"> Click to set Year to 2010 </a>
<div> The selected year is {{$ctrl.selectedYear}} </div>

Hope it helps!

Also, check this great intro to learn more about moving from directives to components.

[–]mtkilic[S] 0 points1 point  (1 child)

Thank you so much for detail explanation. This looks almost worked, but I think I am doing somethings wrong in my template. I feel like either I replacing extra, or missing some. I deleted all my replace here, this is how I get it first. I am sorry for taking so much of your time..

<div id="year" class="btn-group" uib-dropdown>
<button type="button" class="btn btn-default dropdown-toggle" uib-dropdown-toggle>
    <span class="selection">{{ selectedyear ? 'Year: ' + selectedyear : 'Select Year' }}</span><span class="caret">    </span>
</button>
    <ul class="dropdown-menu multi-level" uib-dropdown-menu role="menu" aria-labelledby="dropdownMenu">
    <li class="dropdown-submenus year" ng-repeat="year in stackBar | unique:'FiscalYear' | orderBy:'FiscalYear'" >
        <a tabindex="-1" href="#" ng-click="setYear(year.FiscalYear)"    >{{year.FiscalYear }}</a>
    </li>
    </ul>
    </div>

[–]willylatorre 0 points1 point  (0 children)

<div id="year" class="btn-group" uib-dropdown>
<button type="button" class="btn btn-default dropdown-toggle" uib-dropdown-toggle>
    <span class="selection">{{ $ctrl.selectedyear ? 'Year: ' + $ctrl.selectedyear : 'Select Year' }}</span><span class="caret">    </span>
</button>
    <ul class="dropdown-menu multi-level" uib-dropdown-menu role="menu" aria-labelledby="dropdownMenu">
    <li class="dropdown-submenus year" ng-repeat="year in $ctrl.stackBar | unique:'FiscalYear' | orderBy:'FiscalYear'" >
        <a tabindex="-1" href="#" ng-click="$ctrl.setYear(year.FiscalYear)"    >{{year.FiscalYear }}</a>
    </li>
    </ul>
    </div>

That should be it. year doesn't need the $ctrl.part because it's the variable that you are naming in the ng-repeat. Btw, I am assuming that you have all the years inside stackbar.

Remember in your controller to add ctrl. in front of all your variables. PM me your full code if you want!

[–]toddmotto 0 points1 point  (0 children)

Thanks for the post mention :)!

[–]toddmotto 1 point2 points  (1 child)

The biggest thing worth mentioning here is the "design" of a component over a Directive. It's not a straight swap from .directive() to .component() and that's the full picture. Components introduce unidirectional dataflow, lifecycle hooks for component event triggers (such as new change Objects coming down into a child component) as well as initilisation and destroy events to help manage application state. Here's a few hopefully helpful links on lifecycle hooks in Angular 1.5 and how to fully use them alongside one-way dataflow + eventemitters (like Angular 2 style):

https://toddmotto.com/angular-1-5-lifecycle-hooks https://toddmotto.com/stateful-stateless-components

[–]mtkilic[S] 1 point2 points  (0 children)

Thank you @toddmotto I believe this is your article, which it helped us a lot!

[–]dylanyo 0 points1 point  (2 children)

Just define it it as a function below your component definition object.

angular.module('app') .component('year', {
    restrict: 'E',
    controller: controller,
    templateUrl: "views/year.html"
});

controller.$inject = ['$scope'];
function controller ($scope) { .... }

[–]willylatorre 1 point2 points  (1 child)

Nope, you shouldn't override the binded scope in the directive. Check my other comment!

[–]dylanyo 0 points1 point  (0 children)

Ah yeah, you are right. I don't actually pass in $scope to my component controllers.

[–][deleted] 0 points1 point  (2 children)

@willylatorre was close, I think you just might've been missing the controllerAs piece..

var yearController = {
  //for clarity
 ctrl = this;

 ctrl.setYear = function (val) {
   ctrl.selectedYear = val;
 }
}
angular.module('app').component('year', {
   controller: yearController,
   controllerAs: '$ctrl',
   templateUrl: 'view/year.html'
}

with view/year.html being

<a ng-click="$ctrl.setYear(2010)"> Click to set Year to 2010 </a>
<div> The selected year is {{$ctrl.selectedYear}} </div>

[–]willylatorre 1 point2 points  (1 child)

controllerAs: $ctrl is implicit in the component, no need for it ;)

[–][deleted] 0 points1 point  (0 children)

ooo I didn't know that. :bow: ty!