Angular JS Magazine

luni, 6 octombrie 2014

Giving Each Directive Instance Its Own Scope

By default, multiple instances of the same directive uses the same scope. Here it is a test (you can drop to the link function):

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="../angular/angular.min.js"></script>
    <style type="text/css">
    </style>
    <script>
        angular.module("appModule", [])
                .controller("appCtrl", function ($scope) {
                    $scope.players = [
                        { name: 'Nadal, Rafael (ESP)', rank: 1, age: '28', prizemoney: 66149345 },
                        { name: 'Djokovic, Novak (SRB)', rank: 2, age: '27', prizemoney: 70704129 },
                        { name: 'Federer, Roger (SUI)', rank: 3, age: '33', prizemoney: 84827704 },
                        { name: 'Wawrinka, Stan (SUI)', rank: 4, age: '29', prizemoney: 13155060 },
                        { name: 'Ferrer, David (ESP)', rank: 5, age: '32', prizemoney: 24034072 },
                        { name: 'Tsonga, Jo-Wilfried (FRA)', rank: 11, age: '29', prizemoney: 1708240 },
                        { name: 'Simon, Gilles (FRA)', rank: 26, age: '29', prizemoney: 760469 },
                        { name: 'Lopez, Feliciano (ESP)', rank: 20, age: '33', prizemoney: 1100579 },
                        { name: 'Benneteau, Julien (FRA)', rank: 28, age: '32', prizemoney: 617688 },
                        { name: 'Verdasco, Fernando (ESP)', rank: 33, age: '30', prizemoney: 689219 },
                        { name: 'Mayer, Leonardo (ARG)', rank: 25, age: '27', prizemoney: 946294 }
                    ];
                })
                .directive("dropDown", function () {
                    return {
                        link: function (scope, element, attrs) {
                            var data = scope[attrs["dropDown"]];
                        },
                        template: "<select ng-model='selectedPlayer'
                                            ng-options='item.name group by item.age for item in players'>" +
                                        "<option value=''>(Pick One Player)</option>" +
                                        "</select>"
                    }
                });
    </script>
</head>
<body>
<div ng-app="appModule" ng-controller="appCtrl">

    <label>Select an Player:</label>

    <table>
        <tr>
            <td>
                <div drop-down="players"></div>
            </td>
            <td>
                <div drop-down="players"></div>
            </td>
        </tr>
    </table>
</div>
</body>
</html>


Notice that both instances look the same. When you select a player from the first drop down, it will be selected in the second drop down also, and viceversa. Now, we can adjust the code to give each directive instance its own scope:
...
.directive("dropDown", function () {
                    return {
                        link: function (scope, element, attrs) {
                            var data = scope[attrs["dropDown"]];
                        },
                        template: "<select ng-model='selectedPlayer'
                                            ng-options='item.name group by item.age for item in players'>" +
                                        "<option value=''>(Pick One Player)</option>" +
                                        "</select>",
                        scope:true
                    }
                });
...