AngularJS Directive – Scopes

AngularJS Directivesと使用できるスコープの異なる種類についてお話するつもりです。 呼び出すビュー (HTML) からディレクティブにスコープを渡すには、主に 3 つの方法があります:

  • Default Scope
  • Inherited Scope
  • Isolated Scope

また、孤立したスコープはそれ自体がありえます。

  • Oneway
  • Twoway
  • Method Reference

Default Scope

このタイプでは、外部ビューからのスコープはただ指示子に流れ込んでくるだけです。 別の言い方をすれば、スコープはディレクティブに「参照」として渡されます。 すべてのスコープデータは、ディレクティブ内ですぐに消費できるようになります。

view and directive bound vis scope

This is achieved by specifying the scope as

scope: false // false is the default value

in directive definitions.

下の例では、’name’ はディレクティブの中に飛んでいて、変更があるとすぐに外に反映されます。 スコープがtrueに設定されているので、ディレクティブはその呼び出し元としてスコープを取得します。

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = "Jack";
});// usage: <div upper-case/></div>
myApp.directive('upperCase', function() {
return {
scope: false,
template: 'Name: <input ng-model="name"></input>'
}
});

ライブ演奏は@ https://jsfiddle.net/madhanganesh/830rn1fm/

Inherited Scope

このタイプでは、ビュースコープから新しいスコープが継承されます。 Javascriptでは、オブジェクトはプロトタイプ継承を使用して継承されます。

これは、指示の定義で

scope: true

として範囲を指定することによって実現されます。 この変更は、「継承」されたスコープにより、外部には反映されません。

下の実例では、’name’がdirectiveに飛んでいるのがわかりますが、directiveで行われた変更は外部には反映されません。 これは、controllerのスコープを「継承」するディレクティブのスコープが作成されることを意味します。 javascriptの典型的な継承ルールに従って、派生オブジェクト(ディレクティブのスコープ)は親オブジェクト(コントローラのスコープ)と同じプロパティを参照することになります。 コントローラに加えられたすべての変更は、ディレクティブの “name “プロパティに変更が加えられるまで、ディレクティブに反映されます。

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = "Jack";
});// usage: <div upper-case/></div>
myApp.directive('upperCase', function() {
return {
scope: true,
template: 'Name: <input ng-model="name"></input>'
}
});

ライブフィドルは @ https://jsfiddle.net/madhanganesh/57sb6yg8/

Isolated Scope

このタイプのスコープ定義では、ディレクティブはビューにデータを受信または送信しない独立したスコープを取得します。

これは、ディレクティブ定義で

scope: {}

と指定することにより達成されます。

以下の例では、ディレクティブに空のオブジェクト {} を渡すことにより、孤立したスコープを実現しています。

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = "Jack";
});// usage: <div upper-case/></div>
myApp.directive('upperCase', function() {
return {
scope: {},
template: 'Name: <input ng-model="name"></input>'
}
});

ライブ演奏は @ https://jsfiddle.net/madhanganesh/7d37w08e/

孤立したスコープは、ディレクティブに渡す(および出す)データを完全に制限するよりも、実際はもっと重要です。 一方では、上記の例のようにデータを完全に制限することができます。 しかし、ディレクティブに一つ以上の属性を渡して、それをディレクティブのスコープとして取り込むことは可能です。 柔軟性は、渡された属性がディレクティブの内部でどのように解釈されるかによります。

  • ディレクティブに渡す前に評価される一方通行として
  • 双方向として呼び出すスコープのプロパティへの参照
  • 呼び出すスコープのメソッドへの参照

Expression

以下に示すように、 ディレクティブの呼び出し側は明示的に値を渡すことが可能です。

<div my-directive name='{{name}}' />
// an expression is passed to the directive

ディレクティブの内部で捕捉される方法は次のとおりです:

scope: {
name: '@name'
}

@ 記号は、name 属性を式とみなして、text プロパティに値を割り当てる前にそれを評価するように angular に指示します。 式が評価されるため、一方向のバインディングとなり、ディレクティブ内の値で行われた更新は、外部には反映されません。 これは評価され、ディレクティブの分離されたスコープに割り当てられる式です。

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = 'Jack';
});
// usage: <div my-directive name='{{name}}' />
myApp.directive('upperCase', function() {
return {
scope: {
name: '@name'
},
template: 'Name: <input ng-model="name"></input>'
}
});

ライブフィドルは @ https://jsfiddle.net/madhanganesh/ybzcryt0/4/

name はディレクティブ内のテキストであるため、変更はディレクティブに限定され、親コントローラーとは何も共有されません。

双方向(プロパティへの参照)

ディレクティブの呼び出し側は、次のようにプロパティへの参照をディレクティブに渡すことができます:

<div my-directive name='data.name' />
// a property reference to the directive

ディレクティブ内での捕捉方法は:

scope: {
name: '=name'
}

=シンボルはname属性を呼び出し側の特定のプロパティへの参照としてみなすようangularに指示します。 したがって、値はディレクティブに渡され、属性に加えられた変更は直ちに外部に反映されます。

以下の例では、name 属性がディレクティブに渡されることがわかります。

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = 'Jack';
});
myApp.directive('upperCase', function() {
return {
scope: {
name: '=name'
},
template: 'Name: <input ng-model="name"></input>'
}
});

ライブフィドルは @ https://jsfiddle.net/madhanganesh/o74nvcj3/1/

name はコントローラ内のプロパティへの参照なので、どちらかの変更が両方に反映されます。

メソッドへの参照

ビューの呼び出しから渡される方法は:

<div my-directive nameFn="getName()" />
// a method reference is passed to the directive

ディレクティブ内で捕捉する方法は:

scope: {
nameFn: '& nameFn'
}

&シンボルは、nameFn 属性を呼び出し中のスコープの特定のメソッドの参照としてみなすようアンギュラに指示します。 このメソッドは、必要なときにディレクティブ内から実行することができます。

下の例では、nameFnプロパティは、その参照がディレクティブ内で渡されるメソッドであることがわかります。 この関数はディレクティブから実行されますが、スコープの呼び出しのコンテキストで評価されます。

var myApp = angular.module('myApp', );
myApp.controller('MyController', function($scope) {
$scope.name = 'Jack';
$scope.getName = function() {
return $scope.name;
}
});
myApp.directive('upperCase', function() {
return {
scope: {
nameCb: '&name'
},
//template: 'Name: <input ng-model="nameFn()"></input>'
template: 'Name: {{textCb()}}'
}
});

ライブ演奏は @ https://jsfiddle.net/madhanganesh/6w4msr5k/1/

Summary

このように、ディレクティブスコープには非常に多くのものがありますが、以下の要約は、可能性とその意味について説明しています。 ディレクティブは含まれるビューのスコープから継承されたスコープを取得します

  • Isolated: ディレクティブは、ビューから独立したスコープを取得します
  • そして、孤立したスコープでは、3つの可能性があります:

    Oneway : ディレクティブ属性は式として見なされ、評価されてから、孤立したスコープの特定のプロパティに割り当てられます