Darren Christopher
Darren Christopher

Reputation: 4779

Angular - Function in ControllerAs can not be executed

I am new to Angular and would like to use Modal (Popup form) using ui-bootstrap from Angular. I am learning from Angular bootstrap site. It can be seen that it utilizes ControllerAs to control the popup.

The problem I face is the function in the ctrl cannot be executed in ng-click event, even though I already put the right value ng-click='ctrl.open()'

To make it clearer, I will provide my code below.

Controller.js

'use strict';

function funcListEmployeeCtrl($scope) {
    var ctrl = this;
    ctrl.items = ['item1', 'item2', 'item3'];
    ctrl.animationsEnabled = false;
    console.log(ctrl);
    ctrl.open = function (size, parentSelector) {
        console.log('selected'); //this is not fired
        var parentElem = parentSelector ? 
          angular.element($document[0].querySelector('.change-password-modal-container ' + parentSelector)) : undefined;
    var modalInstance = $uibModal.open({
        animation: ctrl.animationsEnabled,
        ariaLabelledBy: 'modal-title',
        ariaDescribedBy: 'modal-body',
        templateUrl: 'myModalContent.html',
        controller: 'ModalInstanceCtrl',
        controllerAs: 'ctrl',
        size: size,
        appendTo: parentElem,
        resolve: {
            items: function () {
                return ctrl.items;
            }
        }
    });
}

angular.module('listEmployee')
    .controller('listEmployeeCtrl', ['$scope', funcListEmployeeCtrl])
    .controller('ModalInstanceCtrl', function ($uibModalInstance, items) {
        var ctrl = this;
        ctrl.items = items;
        ctrl.selected = {
            item: $ctrl.items[0]
        };

      ctrl.ok = function () {
          $uibModalInstance.close($ctrl.selected.item);
      };

      ctrl.cancel = function () {
          $uibModalInstance.dismiss('cancel');
      };
});

Note that even the console.log('selected'); is not fired. Therefore, it can be concluded that the function is not accessible by ng-click.

View.html

...
<tbody>
    <tr ng-repeat="emp in data.employees|orderBy:orderByField:reverseSort|filter:{ Name: search_value }">
        <td>{{emp.SalesmanId}}</td>
        <td>{{emp.Name}}</td>
        <td>{{emp.Address}}</td>
        <td>{{emp.Phone}}</td>
        <td>{{emp.Email}}</td>
        <td ng-click='ctrl.open()'>{{emp.Username}}</td>
        <td>{{emp.Role}}</td>
    </tr>
</tbody>
...

What I am trying to do is open a modal whenever the user clicks username cell. The HTML is working fine because I have tried changing ng-click to a function in $scope and it is working. Also, the console.log(ctrl); shows the content, so I am sure the ctrl object is set. Below I provide the screenshot of the log.

ctrl object

Note that I got DevTools warning from Chrome, I do not sure how to get rid of it (I use .min.js and not .map). However, I do not think that is the problem. enter image description here

I am not sure where I went wrong. Any helps and guidance would be appreciated.

Upvotes: 0

Views: 59

Answers (2)

Giovani Vercauteren
Giovani Vercauteren

Reputation: 1908

You seem to confuse your current controller with the modalController. You declare controllerAs: 'ctrl' for you modal, but that doesn't mean you can use ctrl in your current controller.

You have two controllers, listEmployeeCtrl and ModalInstanceCtrl. Only the second controller (ModalInstanceCtrl) can use ctrl in its template.

If you want to use ctrl for listEmployeeCtrl as well you'll need to add the ng-controller directive to the view.html.

Using your sample code:

<div ng-controller="listEmployeeCtrl as ctrl">
    ...
    <tbody>
        <tr ng-repeat="emp in data.employees|orderBy:orderByField:reverseSort|filter:{ Name: search_value }">
            <td>{{emp.SalesmanId}}</td>
            <td>{{emp.Name}}</td>
            <td>{{emp.Address}}</td>
            <td>{{emp.Phone}}</td>
            <td>{{emp.Email}}</td>
            <td ng-click='ctrl.open()'>{{emp.Username}}</td>
            <td>{{emp.Role}}</td>
        </tr>
    </tbody>
    ...
</div>

OR

where you describe your route you probably have something along the lines of

.when('...', {
    controller: 'listEmployeeCtrl',
    templateUrl: '.../view.html'
})

there you can add the controllerAs syntax:

.when('...', {
    controller: 'listEmployeeCtrl',
    controllerAs: 'ctrl',
    templateUrl: '.../view.html'
})

Upvotes: 1

geminiousgoel
geminiousgoel

Reputation: 319

You need to pass the modal id to get it open, which is missing!

Upvotes: 0

Related Questions