我正在关注tutorial以使用AngularJS sidenav
实施下拉菜单。我在我的应用程序中使用了组件,因此我的布局与提供的示例不同。
ul
填充了存储在对象中的名称,但功能失败。我缩小它来解决错误是由于无法找到指令父元素控制器。
var controller = $element.parent().controller();
当我在控制台中记录controller
时,它应显示以下控制器功能:
vm.isOpen = isOpen;
vm.toggleOpen = toggleOpen;
vm.autoFocusContent = false;
vm.menu = mainNavService;
vm.status = {
isFirstOpen: true,
isFirstDisabled: false
};
但它返回并清空对象。是因为而不是使用控制器,我在模块上使用Angular的组件方法并使用控制器属性?
问题
为什么在尝试访问控制器时,它不返回任何属性?
app.component('mainnav', {
templateUrl: 'p3sweb/app/components/app/views/main-nav.htm',
controller: ['userService', 'mainNavService', function(userService, mainNavService){
var vm = this;
vm.isOpen = isOpen;
vm.toggleOpen = toggleOpen;
vm.autoFocusContent = false;
vm.menu = mainNavService;
vm.status = {
isFirstOpen: true,
isFirstDisabled: false
};
function isOpen(section) {
console.log('menu.isSectionSelected(section)')
return menu.isSectionSelected(section);
}
function toggleOpen(section) {
console.log(menu.toggleSelectSection(section))
menu.toggleSelectSection(section);
}
}]
})
app.directive('menuToggle', [ '$timeout', function($timeout){
return {
scope: {
section: '='
},
templateUrl: 'p3sweb/app/components/app/views/main-nav-li.htm',
link: function($scope, $element) {
var controller = $element.parent().controller(); //FAILS
$scope.isOpen = function() {
return controller.isOpen($scope.section)
};
$scope.toggle = function() {
console.log(controller.toggleOpen())
controller.toggleOpen($scope.section);
};
}
};
}])
答案 0 :(得分:1)
javascript上下文可以很容易地传递。你可以做的是改变你的menuToggle
指令,如
app.directive('menuToggle', [ '$timeout', function($timeout){
return {
scope: {
section: '=',
context: '=' // NOTE: This is what the parent component will pass
},
templateUrl: 'p3sweb/app/components/app/views/main-nav-li.htm',
link: function($scope, $element) {
var controller = $scope.context; // This is reference to parent
$scope.isOpen = function() {
return controller.isOpen($scope.section)
};
$scope.toggle = function() {
console.log(controller.toggleOpen())
controller.toggleOpen($scope.section);
};
}
};
}])
在你需要做的main-nav.htm
内
<menu-toggle section="blah" context="$ctrl"></menu-toggle>
EDIT ::
功能$scope.isOpen
和$scope.toggle
也是不必要的。 (除非你有一些特定的要求,让你按现在的方式拥有它们)
在main-nav-li.htm
找到isOpen()
的任何地方,将其替换为context.isOpen(section)
以及toggle()
的任何地方,将其替换为context.toggle(section)
答案 1 :(得分:0)
我在jsfiddle运行你的代码,这就是我改变了:
首先,我将组件更改为添加transclude
选项的指令:
app.directive('mainnav', function(){
return {
transclude: true,
template: '<div> <ng-transclude></ng-transclude> <div>',
controller: ['$scope', function($scope){
var vm = this;
vm.autoFocusContent = false;
vm.status = {
isFirstOpen: true,
isFirstDisabled: false
};
}]
}
});
在此之后,您可以像这样访问父控制器:
var controller = $element.parent().controller('mainnav');
以下是完整示例: