Angular JS Magazine

marți, 7 octombrie 2014

Custom Directive - Creating Simplest Isolated Scope

In Custom Directive - Inheritance of Objects and Properties you saw that scopes of different instances of a directive benefit of scopes inheritance of objects and properties. But, the big problem in this case is that technique can lead to awkward behaviors because of the possible interferences caused by the data objects and properties defined on by the controller or elsewhere in the scope hierarchy. For example, the controller may define a selectedPlayer property also. A developer that uses your custom directive doesn't know about the existence of this property in the directive. So, in order to avoid such issues, you need to define an isolated scope. The simplest isolated scope is below (we keep the rest of code from Custom Directive - Inheritance of Objects and Properties):

<!DOCTYPE html>
<head lang="en">
    <meta charset="UTF-8">
    <script src="../angular/angular.min.js"></script>
    <style type="text/css">
    <script type="text/ng-template" id="playerTemplate">
        <div class="panel-body">
                <select ng-model='selectedPlayer'
                     ng-options=' group by item.age for item in players'>
                    <option value=''>(Pick One Player)</option>
            <p>Court: <input ng-model=""/></p>
            <p>Injury: <input ng-model="injury"/></p>
        angular.module("appModule", [])
                .controller("appCtrl", function ($scope) {
                    $scope.injury = "No";
                    $scope.court = {name: "Philippe Chatrier"};
                    $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("nextMatch", function () {
                    return {
                        template: function () {
                            return angular.element(
                        scope: {}
<div ng-app="appModule" ng-controller="appCtrl">
    Next match on Roland Garros:
                <div next-match></div>
                <div next-match></div>
Check the screenshot! All inputs are empty, because there is no inheritance from the controller scope, which means that there are no values defined for any of the properties specified by the ng-model directive.In other words, each directive instance has its own scope, but it doesn't inherit any data values from the controller scope, it was totally disconnected from the rest of the scope hierarchy.