Having trouble reaching the parent controller elements

Currently, I am in the process of following a tutorial on implementing a drop down menu using AngularJS's sidenav. However, due to using components in my application, my layout is different from the provided example.

I have encountered an issue where the functions are not working properly after populating the ul with names stored in an object. Upon investigation, I have discovered that the error stems from the inability to locate the parent element's controller directive.

var controller = $element.parent().controller();

Upon logging the 'controller' in the console, it should display various controller functions:

vm.isOpen = isOpen;
vm.toggleOpen = toggleOpen;
vm.autoFocusContent = false;
vm.menu = mainNavService;
vm.status = {
    isFirstOpen: true,
    isFirstDisabled: false
};

However, it currently returns an empty object. Could this be because rather than utilizing a controller, I am employing Angular's component method within the module and utilizing the controller property?

Inquiry:

Why does attempting to access the controller result in no properties being returned?

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);
            };
        }
    };
}])

Answer №1

Passing a JavaScript context can be quite simple. To achieve this, you can modify your menuToggle directive like so:

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);
            };
        }
    };
}])

Within your main-nav.htm, make sure to include:


<menu-toggle section="blah" context="$ctrl"></menu-toggle>

EDIT::

The functions $scope.isOpen and $scope.toggle may not be necessary (unless there is a specific requirement for them). In your main-nav-li.htm, replace any instances of isOpen() with context.isOpen(section), and replace any occurrences of toggle() with context.toggle(section).

Answer №2

When running your code on jsfiddle, I made some modifications:

Initially, I converted the component into a directive by including the transclude option:

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
          };

      }]
    }
});

Following this change, you can access the parent controller in this manner:

var controller = $element.parent().controller('mainnav');

Here's the complete example for reference:

https://jsfiddle.net/jm65ajjz/2/

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Steps for resetting the counter to 0 following an Ajax Refresh or Submission to the database

I have been working on a code that successfully sends multiple data to a MySQL Database using JQuery Ajax. Everything works smoothly, but I encountered an issue when trying to refresh the page with ajax and add a new record; it populates the number of time ...

Issues arising from CORS in combination with AngularJS, Bearer Tokens, and WebApi

Struggling to establish a connection to a webapi using Angular. Despite researching various problems and potential solutions all day, I still can't get it to function. Here's what I've tried: On the server side, I have this set in my web.c ...

How can the marionette controller object generate unique prototype methods that are dynamic?

Currently, I am working with Marionette to develop an application with multiple pages. The process of instantiating views and displaying them through the appRegion in each controller/router method feels repetitive. My goal is to streamline this process by ...

AngularJS in action for a new Widget Framework

I am working on a project that requires creating a page similar to iGoogle. This page will consist of various drag-and-drop widgets, with each widget representing a distinct application. Does anyone have any advice or recommended links for this type of pr ...

Tips for populating several input fields using an ajax callback

I have a functioning code below that needs to update input fields with values retrieved from an ajax call. I am unsure about the ajax success function that would allow me to callback php variables ($first, $last, etc.) to populate those input fields. Your ...

Guide on incorporating dxTreeView with AngularJS

Hello there, I am trying to utilize the dx-tree-view component. In my Home.html file, I have included the following HTML code: <div dx-tree-view="treeViewOptions"></div> And in my HomeController.js: $scope.treeViewOptions = { binding ...

Decode a JSON string that has already been encoded

Currently, I am dealing with JSON strings in which the quotes are not properly escaped. The strings are structured like this: { "foo" : "hello my name is "michael"" } Is there a practical way in JS/PHP to escape the quotes within the value without manual ...

What is the best way to create a cube in Three.js with the 4 corner points of the base and a specified height?

Given a JSON with base coordinates, I am looking to generate a cube in Three.js. The height of the cube will be a constant value, such as 1. { "points": [ { "x": 0, ...

How can Array.map() be combined with D3 selection?

Is there a way to calculate the maximum length of text elements in an SVG selection similar to using Array.map()? Currently, I am retrieving the maximum length of a selection of SVG <text/> elements by utilizing .selectAll(...)[0].map(...), but it fe ...

What is the best way to conceal a div when there are no visible children using AngularJS?

I need help with hiding a parent div only if all the child items are invisible. I have successfully hidden the parent when there are no children, but I am struggling to figure out how to hide it based on visibility. <div ng-repeat="group in section.gro ...

The submission of the form is prevented upon updating the inner HTML

I am in the process of creating a website that will incorporate search, add, update, and delete functionalities all on a single webpage without any modals. The main focus of this webpage is facility maintenance. Adding facilities works smoothly; however, i ...

I'm facing issues with Webpack not being able to resolve and locate the node

Encountering difficulties while setting up and running the Three.js library as a module based on the guidelines provided in the manual at Here is a summary of the steps taken: Created package.json npm init Installed webpack npm i --save-dev webpack we ...

Exploring the functionality of className using materialUI

Attempting to test whether my component has a specific class is proving challenging. This difficulty stems from the fact that the class is generated using MaterialUI. For instance, I am looking for a class named spinningIconCenter, but in reality, it appea ...

Stopping JavaScript from executing upon the loading of new content with Ajax - a comprehensive guide

During the development of a website, I have implemented Ajax to load content dynamically along with the necessary JavaScript. The reason behind this choice is that all pages share the same layout but have different content. An issue I encountered was that ...

Error: React.js - operationStore.getItems function is not defined

I've encountered an issue while running my Web App with the command: node --harmony gulpfile.babel The error message states: Uncaught TypeError: operationStore.getItems is not a function I'm struggling to identify the root cause of this problem ...

Retrieving the value of the selected item when it is changed

I am currently using v-select/v-autocomplete in my project: <v-autocomplete v-modal="newRole" :items="roles" label="--Change role--" required return-object item-value="id" item-text=&qu ...

What steps can be taken to resolve errors that are specific to a custom binding in use?

Summary: Encountering an error with custom domain binding in Azure, but not with default azurewebsites binding. For example results in an error, while does not trigger the error. Background Information: In my application, I am using Three.js to create ...

What is the correct method for launching a modal window in wagtail-admin?

I am currently working on enhancing my wagtail-admin interface, but I have hit a roadblock when trying to open a modal window. While I could create a div with a close button, I believe there must be a more appropriate method for achieving this. It seems th ...

What is the best way to handle an array (or manually loop through ng-repeat)?

AngularJS Version: 1.3.15 Confession: While I have limited knowledge of AngularJS, I am required to utilize it due to its integration in the framework I am working with. I aim to make changes to some HTML/AngularJS code that currently appears as follows: ...

How can you reset a variable counter while inside a forEach loop?

I am currently working on resetting a counter that is part of a recursive forEach loop within my code. Essentially, the code snippet provided calculates the length of the innermost key-value pair as follows: length = (key length) + (some strings inserted) ...