別のディレクティブを呼び出したいディレクティブがあります。私はこれを達成するためにディレクティブコントローラーを使用しようとしています。
ディレクティブ1はディレクティブ2と同じページにあり、ディレクティブ1はディレクティブ2のコントローラーによって公開されたメソッドを呼び出します。
ディレクティブ1:
'use strict';
angular.module('angularTestApp')
.directive('fileLibrary', function () {
return {
templateUrl: 'views/manage/file_library/file-library.html',
require: 'videoClipDetails',
restrict: 'AE',
link: function postLink(scope, element, attrs, videClipDetailsCtrl) {
scope.doSomethingInVideoClipDirective = function() {
videClipDetailsCtrl.doSomething();
}
}
};
});
ディレクティブ2:
'use strict';
angular.module('angularTestApp')
.directive('videoClipDetails', function () {
return {
templateUrl: 'views/video_clip/video-clip-details.html',
restrict: 'AE',
controller: function($scope, $element) {
this.doSomething = function() {
console.log('I did something');
}
},
link: function postLink(scope, element, attrs) {
console.log('videoClipDetails directive');
//start the element out as hidden
}
};
});
2つが使用され、兄弟として設定されているファイル:
<div>
<div video-clip-details></div>
<!-- main component for the file library -->
<div file-library></div>
</div>
ディレクティブが同じ要素にあるときにコントローラーを共有できることを取り上げたドキュメントを読んでいるので、この問題を間違った方法で見ているのではないかと思います。誰でも私を正しい方向に導くことができますか?
Angular.jsから ディレクティブに関するドキュメント
ディレクティブが
require
を使用する場合、$compile
は、指定されたコントローラーが見つからない限りエラーをスローします。^
プレフィックスは、このディレクティブがその親でコントローラーを検索することを意味します(^
プレフィックス、ディレクティブは独自の要素でのみコントローラーを探します)。
したがって、基本的に兄弟が直接通信することで何をしようとしているかは不可能です。これと同じ問題に遭遇しましたが、通信にサービスを使用したくありませんでした。私が思いついたのは、兄弟である子の間の通信を管理するために親ディレクティブを使用する方法でした。 githubの例 を投稿しました。
起こるのは、両方の子が親(require: '^parentDirective'
)および独自のコントローラー。両方ともリンク関数に渡されます。そこから、各子は、親コントローラーとそのすべてのパブリックメソッドへの参照を、一種のAPIとして取得できます。
以下は、子itemEditor
の1つです
function itemEditor() {
var directive = {
link: link,
scope: {},
controller: controller,
controllerAs: 'vm',
require: ['^itemManager', 'itemEditor'],
templateUrl: 'app/scripts/itemManager/itemManager.directives.itemEditor.html',
restrict: 'A'
};
return directive;
function link(scope, element, attrs, controllers) {
var itemManagerController = controllers[0];
var itemEditorController = controllers[1];
itemEditorController.itemManager = itemManagerController;
itemEditorController.initialize();
}
function controller() {
var vm = this;
// Properties
vm.itemManager = {};
vm.item = { id: -1, name: "", size: "" };
// Methods
vm.initialize = initialize;
vm.updateItem = updateItem;
vm.editItem = editItem;
// Functions
function initialize() {
vm.itemManager.respondToEditsWith(vm.editItem);
}
function updateItem() {
vm.itemManager.updateItem(vm.item);
vm.item = {};
}
function editItem(item) {
vm.item.id = item.id;
vm.item.name = item.name;
vm.item.size = item.size;
}
}
}
require
配列に渡される値が、親ディレクティブの名前と現在のディレクティブの名前であることに注意してください。その後、これらはlink
関数でcontrollers
パラメーターを介してアクセスできます。親ディレクティブのコントローラーを現在の子のコントローラーとして割り当てると、そのプロパティを介して子のコントローラー関数内でアクセスできます。
また、子ディレクティブのlink
関数で、子のコントローラーからinitialize
関数を呼び出す方法にも注目してください。これは、通信回線の一部が確立される場所です。
私は基本的に、あなた(親ディレクティブ)がアイテムを編集するリクエストを受け取ったときはいつでも、editItem
という名前の私のメソッドをitem
をパラメーターとして使用します。
これが親ディレクティブです
function itemManager() {
var directive = {
link: link,
controller: controller,
controllerAs: 'vm',
templateUrl: 'app/scripts/itemManager/itemManager.directives.itemManager.html',
restrict: 'A'
};
return directive;
function link(scope, element, attrs, controller) {
}
function controller() {
var vm = this;
vm.updateMethod = null;
vm.editMethod = null;
vm.updateItem = updateItem;
vm.editItem = editItem;
vm.respondToUpdatesWith = respondToUpdatesWith;
vm.respondToEditsWith = respondToEditsWith;
function updateItem(item) {
vm.updateMethod(item);
}
function editItem(item) {
vm.editMethod(item);
}
function respondToUpdatesWith(method) {
vm.updateMethod = method;
}
function respondToEditsWith(method) {
vm.editMethod = method;
}
}
}
ここで、親では、respondToEditsWith
がメソッドをパラメーターとして取り、その値をeditMethod
プロパティーに割り当てることがわかります。このプロパティは、コントローラのeditItem
メソッドが呼び出され、item
オブジェクトが渡されるたびに呼び出され、子ディレクティブのeditItem
メソッドを呼び出します。同様に、データの保存も同じように逆に機能します。
Update:ところで、ここに coderwall.comのブログ投稿 ここで、 require
およびディレクティブのコントローラーオプション。とは言っても、その投稿の最後の例で彼が推奨した構文は私にとってはうまくいきませんでした。そのため、上記で参照した例を作成しました。
ここでやろうとしている方法で兄弟要素間で通信する必要がある実際の方法はありません。 requireは、2つのディレクティブが同じ要素である場合に設定した方法で機能します。
ただし、両方のディレクティブには使用したいtemplateUrlが関連付けられており、要素ごとに1つしか使用できないため、これを行うことはできません。
ただし、これを機能させるために、HTMLをわずかに異なる構造にすることができます。基本的に、1つのディレクティブを他のディレクティブ(トランスクルード)内に配置し、require: '^videoClipDetails'
。それはそれを見つけるために親に見えることを意味します。これを実証するためにフィドルを設定しました: http://jsfiddle.net/WwCvQ/1/
これは親の事を機能させるコードです:
// In videoClipDetails
template: '<div>clip details<div ng-transclude></div></div>',
transclude: 'true',
...
// in markup
<div video-clip-details>
<div file-library></div>
</div>
// in fileLibrary
require: '^videoClipDetails',
ご質問がある場合はお知らせください!