19
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AngularJSのdirectiveのScopeがよくわからないメモ

Last updated at Posted at 2015-07-28

AngularJSのdirectivを使う場合、独自のscopeを作成できるが、その仕組みがいまいちわからない。

まず、簡単なところから。

属性のscopeをdirectivBのように{}を設定すると。
独自のscopeを作成する。

html
<html ng-app="App" ng-controller="AppCtrl">
<body>
  <directiv-A></directiv-A>
  <directiv-B></directiv-B>
</body>
</html>
js
angular.module('App', [])
  .controller('AppCtrl', ['$scope', function($scope) {
    $scope.value = '親のscopeを継承'
  }])
  .directive('directivA', function() {
    return {
      restrict: 'E',
      template: '<div>scope:{{value}}</div>'
    };
  })
  .directive('directivB', function() {
    return {
      restrict: 'E',
      scope: {},
      template: '<div>scope:{{value}}</div>'
    };
  })
出力結果
scope:親のscopeを継承
scope

サンプル

他にも下記設定方法がある。

  • scope: false ・・・scope属性を設定しない場合と同様の結果。デフォルト値はfalse。
  • scope: true ・・・親scopeを継承し、新しいscopeを作成する。
  • scope: {}  ・・・独立したスコープを作成する

scope: false/tureの設定サンプル

html
<html ng-app="App" ng-controller="AppCtrl">
<body>
  <directiv-A></directiv-A>
  <directiv-A></directiv-A>
  <directiv-A></directiv-A>
  <directiv-B></directiv-B>
  <directiv-B></directiv-B>
  <directiv-B></directiv-B>
</body>
</html>
js
angular.module('App', [])
  .controller('AppCtrl', ['$scope', function($scope) {
    $scope.value = '親のscopeを継承'
  }])
  .directive('directivA', function() {
    return {
      restrict: 'E',
      scope: false,
      template: '<div>scope: true:{{value}}  id:{{id}}</div>',
      controller: function($scope) {
        $scope.id = $scope.$id;
      }
    }
  })
  .directive('directivB', function() {
    return {
      restrict: 'E',
      scope: true,
      template: '<div>scope: true:{{value}}  id:{{id}}</div>',
      controller: function($scope) {
        $scope.id = $scope.$id;
      }
    };
  });
出力結果
scope: false:親のscopeを継承 id:2
scope: false:親のscopeを継承 id:2
scope: false:親のscopeを継承 id:2
scope: true:親のscopeを継承 id:3
scope: true:親のscopeを継承 id:4
scope: true:親のscopeを継承 id:5

サンプル

独立したスコープを作成する

scope:'='を使う

子Scopeと親Scopeを双方向バインディングさせる。
親Scopeが変更されれば、子Scopeも変更される。子が変更されれば、親も変更される。
親scopeで子scopeの管理がしやすくなる。

js
angular.module('App', [])
  .controller('AppCtrl', ['$scope', function($scope) {
    $scope.test = '双方向でバインド'
    $scope.test2 = '双方向でバインド2'
  }])
  .directive('directivA', function() {
    return {
      restrict: 'E',
      template:'<div>directivA : {{itemA}}</div>',
      scope: {
        itemA: '='
      }
    };
  });
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
  <div>{{test}}</div>
  <div>{{test2}}</div>
  <br>
  <directiv-A item-A="test"></directiv-A>
  <directiv-A item-A="test2"></directiv-A>
</body>
</html>
出力結果
双方向でバインド
双方向でバインド2

directivA : 双方向でバインド
directivA : 双方向でバインド2

サンプル

scope:'@'を使う

scopeのプロパティに指定した文字列がそのまま渡ります。
親scopeにはバインドされない。

js
angular.module('App', [])
  .controller('AppCtrl', ['$scope', function($scope) {}])
  .directive('directivB', function() {
    return {
      restrict: 'E',
      template: '<div>directivB : {{itemB}}</div>',
      scope: {
        itemB: '@'
      }
    };
  });
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
  <directiv-B item-B="文字列が入ります"></directiv-B>
</body>
</html>
出力結果
directivB : 文字列が入ります

サンプル

scope:'&'を使う

関数を指定する。(配列とか、数値とか、文字列とか指定できるみたいだが、関数を指定することが多いようです)

例1

js
angular.module('App', [])
  .controller('AppCtrl', ['$scope', function($scope) {
    $scope.func = function() {
      $scope.message = 'こんにちは';
    }
  }])
  .directive('directivC', function() {
    return {
      restrict: 'E',
      scope: {
        itemC: '&'
      },
      controller: function($scope) {
        $scope.itemC();
      }
    };
  });
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
  {{message}}
  <directiv-C item-C="func()"></directiv-C>
</body>
</html>
出力結果
こんにちは

サンプル

例2

js
angular.module('App', [])
  .controller('AppCtrl', ['$scope', function($scope) {
    $scope.func = function(mess){
      console.log('こんにちは')
    }
  }])
  .directive('directivC', function() {
    return {
      restrict: 'E',
      template: '<button ng-click="itemC()">ボタン</button>',
      scope: {
        itemC: '&'
      }
    };
  });
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
  <directiv-C item-C="func(message)"></directiv-C>
</body>
</html>
出力結果
こんにちは

サンプル

例3

引数を連携する。

js
angular.module('App', [])
  .controller('AppCtrl', ['$scope', function($scope) {
    $scope.func = function(mes, mes2) {
      $scope.message = mes + mes2;
    }
  }])
  .directive('directivC', function() {
    return {
      restrict: 'E',
      scope: {
        itemC: '&'
      },
      controller: function($scope) {
        $scope.itemC({
          mes: 'こんにちは',
          mes2: '太郎さん'
        });
      }
    };
  });
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
  {{message}}
  <directiv-C item-C="func(mes,mes2)"></directiv-C>
</body>
</html>
出力結果
こんにちは太郎さん

サンプル

例4

&で配列を入れてみる。

js
angular.module('App', [])
  .controller('AppCtrl', ['$scope', function($scope) {
    $scope.array = [1, 2, 3];
  }])
  .directive('directivC', function() {
    return {
      restrict: 'E',
      scope: {
        itemC: '&'
      },
      controller: function($scope) {
        console.log($scope.itemC())
      }
    };
  });
html
<html ng-app="App" ng-controller="AppCtrl">
<body>
  <directiv-C item-C="array"></directiv-C>
</body>
</html>
出力結果
[1, 2, 3]

これは'='を使えばいいのではないかと思うが、子scopeにバインドしたくない場合などに使うのかな・・・

サンプル

まだ理解が浅い為、追記していく予定。

19
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?