@Josh 在他的回答中提到
最好的解决方案directiveB
是directiveA
使用require
.
我一直在玩这个,我相信控制器directiveA
是唯一的解决方案(所以+1 Josh)。这是使用 OP 的小提琴的作用域的样子:
(反转棕色箭头,您将获得 $$previousSibling 而不是 $$nextSibling。)
除了$$previousSibling
,作用域 004 没有隔离作用域 003 的路径。请注意,作用域 004 是directiveA
创建的嵌入作用域,由于directiveB
不创建新作用域,因此该作用域也被 使用directiveB
。
由于您希望与之共享的对象directiveB
是在directiveA
的控制器中创建的,因此我们也不能使用属性在指令之间共享数据。
在指令中创建模型,然后将该模型共享给外部世界是相当不典型的。通常,您需要在指令之外甚至在控制器之外定义模型(听几分钟 Misko)。服务通常是存储模型/数据的好地方。控制器通常应该引用模型中需要投影到与它们关联的视图中的部分。
为简单起见,我将在控制器上定义模型,然后指令将以正常方式访问此模型。出于教学目的,directiveA
仍将使用隔离范围,并将使用@Josh 的答案directiveB
创建一个新的子范围。scope: new
但是任何类型(隔离、新子、无新范围)和组合都可以工作,因为我们已经在父范围中定义了模型。
控制:
$scope.model = {value: '#33ff33', checkedState = true};
HTML:
<div ng-controller="NoTouchPrevSibling">
<div data-directive-a data-value="model.value" data-checked="model.checkedState">
<div data-directive-b></div>
</div>
出于其他教学原因,我选择将两个模型属性作为单独的属性传递指令 A,但也可以传递整个模型/对象。由于directiveB 将创建一个子范围,它不需要传递任何属性,因为它可以访问所有父/控制器范围属性。
指令:
app.directive('directiveA', function () {
return {
template: '<div>'
+ 'inside parent directive: {{checkedState}}'
+ '<input type="checkbox" ng-model="checkedState" />'
+ '<div ng-transclude></div>'
+ '</div>',
transclude: true,
replace: true,
scope: {
value: '=',
checkedState: '=checked'
},
};
});
app.directive('directiveB', function () {
return {
template: '<div>'
+ '<span>inside transcluded directive: {{model.checkedState}}</span>'
+ '<input type="text" ng-model="model.value" />'
+ '</div>',
replace: true,
scope: true
};
});
范围:
请注意,directiveB 的子作用域 (006) 继承自指令 A 的嵌入作用域 (005)。
单击复选框并更改文本框中的值后:
请注意,Angular 会处理更新隔离范围属性。正常的JavaScript 原型继承使指令 B 的子范围可以访问model
控制器范围 (003) 中的 。
小提琴