[英]How to make a child directive aware of all of its parents in angular?
This is a slightly long one. 这有点长。
How can I have child directives that are aware of all of their ancestors, not just their immediate parent? 我怎样才能让孩子的指令了解他们的所有祖先,而不仅仅是他们的直系父母?
The reason I'm asking is that I want to have a Raphael paper directive that provides a reference to a Raphael paper to all its children. 我要问的原因是我想要一个Raphael纸指令,该指令为其所有子项提供对Raphael纸的引用。 Also, I'm trying to have a "rl-shape" directive that can group different shapes together so they can be translated, transformed, etc. together all at once. 另外,我正在尝试使用“ rl-shape”指令,该指令可以将不同的形状组合在一起,以便可以一次将它们一起转换,变换等。 I'd also like this "rl-shape" directive to be able to appear inside of itself, allowing for arbitrary trees of shapes. 我也希望这个“ rl-shape”指令能够出现在自身内部,允许任意形状的树。
There might be a completely different, better way to do this. 可能会有一种完全不同的更好的方法。 If so, please correct me. 如果是这样,请纠正我。
Here's the code I have so far: 这是我到目前为止的代码:
<!doctype html>
<html xmlns:ng="http://angularjs.org" ng-app="myApp">
<head>
<title>Test</title>
<script src="js/underscore.js"></script>
<script src="js/raphael-min.js"></script>
</head>
<body>
<rl-paper>
<rl-shape name="myShape">
<rl-circle name="inner" cx="0" cy="0" r="50"></rl-circle>
<rl-circle name="outer" cx="0" cy="0" r="100"></rl-circle>
</rl-shape>
</rl-paper>
<p>
<button ng-click="myShape.translate(0, -10)">Move shape up</button>
<button ng-click="myShape.translate(0, 10)">Move shape down</button>
</p>
<script src="js/angular.min.js"></script>
<script>
var myApp = angular.module("myApp", []);
function Shape(children) {
this.translate = function(dx, dy) {
_.each(children, function(c) { c.translate(dx, dy); });
};
}
myApp.directive("rlPaper", function() {
return {
restrict: "E",
controller: function($element) {
this.paper = new Raphael($element[0], 220, 220);
this.paper.setViewBox(-110, -110, 220, 220);
}
};
});
myApp.directive("rlShape", function () {
return {
restrict: "E",
require: ["^rlPaper"],
controller: function($scope, $element, $attrs, $transclude) {
this.children = [];
},
link: function(scope, element, attrs, ctrls) {
// How can the link function of the rlShape directive access its
// own controller? If I could figure that out, I could do
// something like the following:
var shapeCtrl = undefined; // Don't know how to get this
var shape = Shape(shapeCtrl.children);
scope[attrs.name] = shape;
}
};
});
myApp.directive("rlCircle", function() {
return {
restrict: "E",
require: ["^rlPaper", "?^rlShape"],
link: function(scope, element, attrs, ctrls) {
var paperCtrl = ctrls[0];
var shapeCtrl = ctrls[1];
var circle = paperCtrl.paper.circle(attrs.cx, attrs.cy, attrs.r);
scope[attrs.name] = circle;
if ( shapeCtrl ) {
shapeCtrl.children.push(circle);
}
}
};
});
</script>
</body>
</html>
(You have quite a few questions in your question. You'll get better, and likely faster, answers, if you post separate questions for each, with a minimalistic fiddle or plunker demonstrating the problem/question.) (您的问题中有很多问题。如果您针对每个问题分别发布问题,并用简单的小提琴或小插曲来展示问题,则您会得到更好的答案,并且可能更快。)
How can I have child directives that are aware of all of their ancestors, not just their immediate parent? 我怎样才能让孩子的指令了解他们的所有祖先,而不仅仅是他们的直系父母?
If a directive does not create an isolate scope (in the sample code you provided, none of your directives are doing this), then the directive has access to all ancestors' $scopes via normal JavaScript prototypal inheritance . 如果指令未创建隔离范围(在您提供的示例代码中,您的指令都没有执行此操作),则该指令可以通过正常的JavaScript原型继承访问所有祖先的$ scope。
So if you define your data on your directives' $scope
s, the child directives will be able to access that data directly: 因此,如果您在指令的$scope
上定义数据,则子指令将能够直接访问该数据:
Eg, if you have this code in a parent directive's controller function: 例如,如果您在父指令的控制器功能中包含以下代码:
$scope.paper = new Raphael($element[0], 220, 220);
Then child directives can access it (in their controller or link functions): 然后子指令可以访问它(在其控制器或链接功能中):
var paper = $scope.paper; // prototypal inheritance will find it
I want to have a Raphael paper directive that provides a reference to a Raphael paper to all its children. 我想要一个Raphael纸指令,该指令为其所有子项提供对Raphael纸的引用。
So, in the rlPaper
directive, define a "Raphael paper" object on that directive's $scope
(not on this
). 因此,在rlPaper
指令中,在该指令的$scope
上定义一个“ Raphael paper”对象(不在this
)。 Do this in the directive's controller function, not the link function, because the link function will run too late. 在指令的控制器功能(而不是链接功能)中执行此操作,因为链接功能将运行得太晚。 ( Fiddle showing when directive's controller and link functions run, with two nested directives.) (显示了指令的控制器和链接函数何时运行以及带有两个嵌套指令的小提琴 。)
How can the link function of the rlShape directive access its own controller? rlShape指令的链接函数如何访问其自己的控制器?
There is a way to do this, but I think the better way is to put your data and functions on the directive's $scope
, which is shared by the directive's link and controller functions. 有一种方法可以执行此操作,但是我认为更好的方法是将数据和函数放在指令的$scope
,该指令由指令的链接和控制器函数共享。
In the rlCircle
directive, you don't have to require other parent controllers if you instead put your data onto the $scope
objects. 在rlCircle
指令中,如果您将数据放到$scope
对象上,则无需其他父控制器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.