问题
Can a child directive require a parent without knowing exactly which directive that parent is, just that it "implements an interface"?
For example:
<parentImplX>
<child></child>
</parentImplX>
In the above example I want the controller injected into child to be ParentImplXCtrl
. But If I do:
<parentImplY>
<child></child>
</parentImplY>
I want the controller to be ParentImplYCtrl
.
directives.directive("parentImplX", function () {
return {
scope: {},
restrict: "E",
controller: ParentImplXCtrl
}
});
directives.directive("parentImplY", function () {
return {
scope: {},
restrict: "E",
controller: ParentImplYCtrl
}
});
directives.directive("child", function () {
return {
scope: {},
restrict: "E",
require: "?^^parentInterface",
link: function ($scope, $element, attributes, parent /* type ParentInterface */) {
parent.method();
}
}
});
回答1:
I've found that angular 'require' does not support this. However, AngularJS stores the controllers as well as the $scopes
of $element
s in the $element.data()
construct. So it was very simple to write your own 'interface require'. You need to traverse $element.parent().data()
and make sure there is an identifier to look for. In my case isFocusNode
. Note: `FocusNode can have many implementations. It is the whole point.
function findFocusNodeParent(_element) {
var data = _element.data();
for (var key in data) {
var angularObject = data[key];
if (angularObject.isFocusNode && angularObject.isFocusNode()) {
return angularObject;
}
}
var _parentElement = _element.parent();
if (_parentElement.length > 0) {
return findFocusNodeParent(_parentElement);
} else {
// No parent FocusNode found. Must be root
return null;
}
}
var parentFocusNodeController = findFocusNodeParent($element);
来源:https://stackoverflow.com/questions/27946564/can-i-require-generic-parent-directive-in-angularjs