Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I not use $ctrl. in angular component template

I am using angular 1.5 and I wanted to extract part of my DOM into a component.
Here is what I have done so far:

angular.module('my-app').component("menuItem",{
    templateUrl : "lib/menu-item.tmpl.html",
    bindings : {
        index : "<",
        first : "<",
        last : "<",
        item : "=",
        onDelete : "&",
        onMoveUp : "&",
        onMoveDown : "&"
    },
    controller : function($scope) {
    }
});

And the template looks like so:

<div>
    <aside class="sort-buttons">
        <ul>
            <li>
                <button ng-click="$ctrl.onMoveUp({index : $ctrl.index})"
                        ng-disabled="$ctrl.first">
                    <i class="icon icon-up"></i>
                </button>
            </li>
            <li>
                <button ng-click="$ctrl.onMoveDown({index : $ctrl.index})"
                        ng-disabled="$ctrl.last">
                    <i class="icon icon-down"></i>
                </button>
            </li>
        </ul>
    </aside>

    <div class="row">
        <button class="btn btn-danger btn-icon btn-remove"
                ng-click="$ctrl.onDelete({index : $ctrl.index})">
            <i class="icon icon-remove"></i>
        </button>
    </div>
</div>

I use this component (far from finished!) like so:

<section class="container menu">
    <menu-item index="$index" first="$first" last="$last" item="item"
            on-delete="removeItem(index)"
            on-move-up="moveItemUp(index)"
            on-move-down="moveItemDown(index)"
            ng-repeat="item in menu">
    </menu-item>
    <!-- some other display details of `$ctrl.item` -->
</section>

I have three main questions I guess:

  1. Why do I have to use $ctrl everywhere in my template? There is $scope so why all the bindings go to $ctrl rather than $scope? And is there a way to change this?
  2. Can I somehow have values like $index, $first and $last passed in? It seems to me like it is a "buttery butter" to pass them in...
  3. Is this even the right approach? Or should I use directive? I know components have isolated scope, and directives can have not-isolated scope. but could I mix/match in a directive (share the scope with controller, but also add my own functions to be used within directive/template only?)

Thanks for your help.

like image 559
Daniel Gruszczyk Avatar asked Feb 25 '16 13:02

Daniel Gruszczyk


People also ask

What are the elements that we can use in Angluar templates?

This template uses typical HTML elements like <h2> and <p> , and also includes Angular template-syntax elements, *ngFor , {{hero.name}} , (click) , [hero] , and <app-hero-detail> . The template-syntax elements tell Angular how to render the HTML to the screen, using program logic and data.

What is $Ctrl in Angular?

$ctrl is the view model object in your controller. This $ctrl is a name you choose (vm is another most common name), if you check your code you can see the definition as $ctrl = this; , so basically its the this keyword of the controller function.

Can a component have multiple templates Angular?

You can simply extend your base component and overwrite the template. This allows you to have different components with the exact same functionality, but different templates.

What is component template in Angular?

A template is an HTML snippet that tells Angular how to render the component in angular application. The template is immediately associated with a component defines that component's view.


1 Answers

Why do I have to use $ctrl everywhere in my template? There is $scope so why all the bindings go to $ctrl rather than $scope? And is there a way to change this?

$scope will disappear with angular 2.0. You are not obliged to use $ctrl. I recommend that you still use "controllerAs" with a named controller, in order to avoid confusion inside your templates.

controllerAs: "menuItemCtrl",
controller : function($scope) {
},

and then :

            <button ng-click="menuItemCtrl.onMoveUp({index : menuItemCtrl.index})"
                    ng-disabled="menuItemCtrl.first">
                <i class="icon icon-up"></i>
            </button>

to use your bounded variables inside your controller, you have to use this :

controller : function() {
    var self = this;
    // self.index contains your index
}

Can I somehow have values like $index, $first and $last passed in? It seems to me like it is a "buttery butter" to pass them in...

I don't really understand how you want them to be passed.

Is this even the right approach? Or should I use directive?

When you're facing an application that can be displayed as a tree of components, components are the best option.

like image 179
Deblaton Jean-Philippe Avatar answered Sep 20 '22 23:09

Deblaton Jean-Philippe