嗨,我正在尝试制作一个窗格系统,在这个系统中,子指令上的elem.bind('change,.)改变了“选择的”父指令:http://plnkr.co/edit/gc35fuUiJVUhHF4QMAwv?p=preview
(function(angular) {
'use strict';
angular.module('docsTabsExample', [])
.directive('myTabs', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: function($scope) {
var panes = $scope.panes = [];
$scope.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false;
});
pane.selected = true;
};
$scope.next = function(pane) {
select(panes[panes.indexOf(pane)+1]);
};
this.addPane = function(pane) {
if (panes.length === 0) {
$scope.select(pane);
}
panes.push(pane);
};
},
templateUrl: 'my-tabs.html'
};
})
.directive('myPane', function() {
return {
require: '^myTabs',
restrict: 'E',
transclude: true,
scope: {
title: '@'
},
link: function(scope, element, attrs, tabsCtrl) {
tabsCtrl.addPane(scope);
},
templateUrl: 'my-pane.html'
};
})
.directive('pf-data', function() {
return {
require: '^myPane',
restrict: 'AEC',
scope: {
title: '@'
},
link: function(scope, element, attrs, tabsCtrl) {
console.log("hi");
element.bind('change', function() {
scope.next();
console.log("switch panes");
});
}
};
});
})(window.angular);(当您选择性别(无论是男性还是女性)时,我希望它依次转到下一个窗格,但由于范围问题(我对角比较生疏),它永远不会进入子指令的链接属性。
有什么想法吗?
发布于 2015-05-02 18:29:20
每个指令都定义了一个独立的作用域(除了指令定义的scope成员的内容外,它几乎是空的。因此,当您说scope.next()时,如果它不是在这个集合中,或者不是由link函数显式附加,它就会失败。所以用$scope联系你的父母是行不通的。当然,您不希望通过属性传递函数来泄漏内部细节。这将使这些相互关联的指令落空。
但你有更好的东西。
因为您使用require将您的指令链接到一起,所以您甚至不必费心于这些游戏。在pf-data中,您将定义:
require: ['^myPane', '^myTabs]这将使您可以直接访问两个控制器。您需要在next指令中公开myTabs。老实说,我会想出一种方法来使用索引,而不是循环遍历所有设置为true和false的窗格。类似于:
var currentPane;
this.next = function() {
select(nextPane(currentPane));
};现在,在pf-data中,您可以通过您的link函数访问:
link: function(scope, element, attrs, ctrls) {
element.bind('change', function() {
$scope.$apply(function() {
ctrls[1].next();
scope.next();
};
});
...更新
我从你提供的新Plnkr中分叉出一个新的Plnkr来整合我们已经讨论过的更改。我还从pf-data中删除了require myPane (因为有了transclude,无论如何也不会起作用)。
http://plnkr.co/edit/LP0RYu6AKxeKyhHY5rZP?p=preview
最新情况包括:
pf-data变成了pfData --这只是角度的规则之一。您的指令使用camel大小写命名,但在html中以连字符大小写结尾。scope.$apply并将require更改为使用myTabs。正如我们在注释中讨论的那样,您需要在捕获不是角的直接部分的事件时使用$apply,以便向屏幕上的元素发出更新信号。myTabs中的所有方法反弹到this上,而不是$scope上。你会需要他们在那里,因为你是通过控制器机制的他们。next(),而不必提供窗格。发布于 2015-05-02 18:11:29
你是对的-这是一个范围问题。使用隔离作用域时,指令中唯一可用的作用域变量是通过属性传入的。要调用在指令内部的父作用域中定义的next(),将方法传递给带有'&‘绑定的属性:
scope: {
title:'@',
next: '&'
}HTML:
<my-pane next="next()"></my-pane>https://stackoverflow.com/questions/30005109
复制相似问题