Leo
Leo

Reputation: 1505

angularjs scope function of a repeated directive

I am trying to have a directive with a repeat on it and have it call a function on the parent control as well as child controls. however when I add a scope: { function:&function} the repeat stops working properly.

fiddle

the main.html is something like

<div ng-app="my-app" ng-controller="MainController">
    <div>
        <ul>
        <name-row ng-repeat="media in mediaArray" on-delete="delete(index)" >
        </name-row>
        </ul>
    </div>
</div>

main.js

var module = angular.module('my-app', []);

function MainController($scope)
{
    $scope.mediaArray = [
        {title: "predator"},
        {title: "alien"}
    ];
    $scope.setSelected = function (index){
        alert("called from outside directive");
    };
    $scope.delete = function (index) {
        alert("calling delete with index " + index);
    }

}

module.directive('nameRow', function() {
    return {
        restrict: 'E',
        replace: true,
         priority: 1001, // since ng-repeat has priority of 1000
        controller: function($scope) {
            $scope.setSelected = function (index){
                alert("called from inside directive");
            }
        },
        /*uncommenting this breaks the ng-repeat*/
        /*
        scope: {
        'delete': '&onDelete'
        },
        */
        template:
'            <li>' +
'                <button ng-click="delete($index);">' +
'                    {{$index}} - {{media.title}}' +
'                </button>' +
'            </li>'
    };
});

Upvotes: 0

Views: 163

Answers (2)

Raulucco
Raulucco

Reputation: 3426

As klauskpm said is better to move common logic to an independent service or factory. But the problem that i see is that the ng-repeat is in the same element of your directive. Try embed your directive in an element inside the loop and pass the function in the attribute of that element or create a template in your directive that use the ng-repeat in the template

<li ng-repeat="media in mediaArray" >
    <name-row on-delete="delete(media)" ></name-row>
</li>

Upvotes: 1

klauskpm
klauskpm

Reputation: 3145

As I've suggested you, the better approach to share methods is building a Factory or a Service, just like bellow:

app.factory('YourFactory', function(){
    return {
        setSelected: function (index){
            alert("called from inside directive");
        }
    }
};

And you would call it like this:

function MainController($scope, YourFactory) {
    $scope.setSelected = YourFactory.setSelected;
    // Could even use $scope.yf = YourFactory;, and call yf.setSelected(index);
    // at your view. 
    (...)

module.directive('nameRow', function(YourFactory) {
    (...)
    $scope.setSelected = YourFactory.setSelected;
    (...)

Hope it will help you.

Upvotes: 0

Related Questions