How to access wrapped variables in a directive?

46 views Asked by At

I have an object which consists of multiple arrays:

$scope.myArrays = {
    array1: ['Pizza', 'Spaghetti'],
    array2: ['Lasagne', 'Schnitzel']
};

Moreover, I have a custom directive to which I want to pass this object myArrays and bind those arrays to scope variables:

<my-directive my-data="myArrays"></my-directive>

myApp.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: {
            arrayOne: '=myData.array1',
            arrayTwo: '=myData.array2'
        },
        link: function(scope, elem) {
            // get access to scope.array1 and scope.array2
        }
    };
});

All together in a fiddle for you to play around!

Is there a way to bind the arrays directly or do I need to bind arrays: '=myArrays' and access them like arrays.array1?

4

There are 4 answers

0
ShankarSangoli On BEST ANSWER

Binding has to be one to one, you cannot do that. Yes, you will have to access the arrays inside your directive.

myApp.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: {
            myData: '='
        },
        link: function(scope, elem) {
           scope.arrayOne = scope.myData.array1;
           scope.arrayTwo = scope.myData.array2;
        }
    };
});

You can directly access scope.myData.array1 and scope.myDate.array2 inside the directive template if you dont have to process these arrays in the link function and get rid of it.

0
LionC On

You could do this by just assigning them to scope fields:

myApp.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: {
            myData: '='
        },
        link: function(scope, elem) {
            scope.arrayOne = myData.array1;
            scope.arrayTwo = myData.array2;
        }
    };
});

However, I would recommeend to just bind the object and to get rid of the link-function. That way the directives code is a lot shorter, more readable, less "black magic" happens and the references inside the directive are more expressive:

myApp.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: {
            myData: '='
        }
    };
});

Then you can just reference it inside the directive with myData.array1. Replace the '=' with '=someName' to reference it with someName.array1

1
Freezystem On

your HTML should be :

<my-directive arrayone="myData.array1" arraytwo="myData.array2"></my-directive>

and your directive :

myApp.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: {
            arrayOne: '=arrayone',
            arrayTwo: '=arraytwo'
        },
        link:function(scope){
            console.log('arrayOne :',scope.arrayOne);
            console.log('arrayTwo :',scope.arrayTwo);
        },
        controller: function($scope) {
            console.log('arrayOne :',$scope.arrayOne);
            console.log('arrayTwo :',$scope.arrayTwo);
        }
    };
});
1
Raja Jaganathan On

Demo

HTML-Partial:

<div ng-controller="MyCtrl">
    <my-directive my-data="myArrays" array-one="myArrays.array1" array-two="myArrays.array2">
    </my-directive>
</div>

Script:

angular.module('myApp', [])

.directive('myDirective', function() {
    return {
        restrict: 'E',
        scope: {
            arrayOne: '=',
            arrayTwo: '='
        },
        link: function(scope, elem) {
            // get access to scope.array1 and scope.array2
             //console.log(scope.array1)
             console.log(scope.arrayOne); 
             console.log(scope.arrayTwo);          

        }
    };
})

.controller('MyCtrl', function($scope) {
    $scope.myArrays = {
        array1: ['Pizza', 'Spaghetti'],
        array2: ['Lasagne', 'Schnitzel']
    };
});