igogra
igogra

Reputation: 465

ng-click in a ng-repeat within a directive

I have a directive with a template to show a table of persons (name, nationality, dates and a button Details). When the button Details is clicked and alert is displayed. The problem is that I don't know how to make the ng-click of the button to work in the ng-repeat inside the directive. They told me to use the following configuration for the directive, using the show function from the controller for the ng-click:

angular.module('app', []).directive('persons', function() {
    return {
        restrict: 'E',
        scope: {
            data: '=',
            action: '&'
        },
        template: '...'
    };
});

The controller:

angular.module('app', []).controller('labController', [function() {
    var vm = this;

    vm.persons = [{
        name: 'Mark Twatin',
        nationality: 'American',
        dates: '1835-1910'
    }, {
        name: 'A. A. Milne',
        nationality: 'English',
        dates: '1882-1956'
    }, {
        name: 'Ernest Hemingway',
        nationality: 'American',
        dates: '1899-1961'
    }, {
        name: 'Charles Dickens',
        nationality: 'English',
        dates: '1812-1870'
    }, {
        name: 'Jane Austen',
        nationality: 'English',
        dates: '1775-1817'
    }];

    vm.show = show;

    function show(person) {
        alert('Show details for: ' + person.name);
    }
}]);

So I added the following template:

<table class="table">
    <thead>
        <th>Name</th>
        <th>Nationality</th>
        <th>Dates</th>
        <th></th>
    </thead>
    <tbody>
        <tr ng-repeat="person in data">
            <td>{{person.name}}</td>
            <td>{{person.nationality}}</td>
            <td>{{person.dates}}</td>
            <td>
                <input 
                    type="button" 
                    ng-click="action(person)" 
                    value="Details" 
                    class="btn btn-primary"
                />
            </td>
        </tr>
    </tbody>
</table>

And the HTML:

<body ng-app="app">
    <div class="container" ng-controller="labController as vm">
        <h1>Directives</h1>
        <persons data="vm.persons"></persons>
    </div>
</body>

So, how can I make the button Details work?

I've created the following fiddle: http://jsfiddle.net/6xyztpxt/3/

Upvotes: 1

Views: 689

Answers (2)

Watto
Watto

Reputation: 81

I've made some changes to your fiddle. I've changed the directive scope for action to '=', so you can access directly to the controller method "show".

scope: {
        data: '=',
        action: '='
    },       

http://jsfiddle.net/6xyztpxt/6/

Upvotes: 0

Ron Dadon
Ron Dadon

Reputation: 2706

You need to change your call inside of the directive for the ngClick.

In a directive, if you want to call a bound function with parameters, you need to pass it an object with to parameters.

Change the ng-click in the template to this: ng-click="action({person: person})" That means, call the action bounded function with a parameter person that has the value of the current person in the ngRepeat.

Then you need to bind your controller show function to the directive like so:

    <persons data="vm.persons" action="vm.show(person)"></persons>

That means, bind the vm.show function as the action to the directive, and when is called pass a parameter person to it.

I have updated your fiddle: http://jsfiddle.net/gmm8a06q/1/

Upvotes: 3

Related Questions