Invoking a parent controller method from a directive in AngularJS

I have utilized a tree grid plugin from the following link: https://github.com/khan4019/tree-grid-directive

and I made some customizations to its template:

.directive('treeGrid', [
    '$timeout', function($timeout) {
      return {
        restrict: 'E',
        template: 
          "<div class=\"table-responsive\">\
            <table id=\"policies\" class=\"table table-striped\">\
                <colgroup>\
                    <col width=\"10%\" />\
                    <col width=\"70%\" />\
                    <col width=\"1%\" />\
                    <col width=\"1%\" />\
                </colgroup>\
                <thead>\
                    <tr>\
                        <th>Category</th>\
                        <th>Content</th>\
                        <th></th>\
                        <th></th>\
                        <th></th>\
                    </tr>\
                </thead>\
                <tbody>\
                    <tr ng-repeat=\"row in tree_rows | filter:{visible:true} track by row.branch.uid\" ng-class=\"'level-' + {{ row.level }} + (row.branch.selected ? ' active':'')\">\
                    <td class=\"text-primary\"><a ng-click=\"user_clicks_branch(row.branch)\"><i ng-class=\"row.tree_icon\"ng-click=\"row.branch.expanded = !row.branch.expanded\"class=\"indented tree-icon\"></i></a>\
                    <span class=\"indented tree-label\" ng-click=\"user_clicks_branch(row.branch)\"> {{row.branch[expandingProperty]}}</span></td>\
                    <td ng-bind-html=\"row.branch[colDefinitions[2].field]\"></td>\
                    <td> <a href=\"javascript:void(0)\" ng-click=\"editContent(row.branch)\" data-toggle=\"modal\" data-target=\"#new-content\" class=\"action\"><i class=\"glyphicon glyphicon-edit\"></i></a> </td>\
                    <td> <a ng-click=\"deleteContent(row.branch.Id)\" class=\"action\"><i class=\"glyphicon glyphicon-remove-circle\"></i></a> </td>\
                    </tr>\
                </tbody>\
            </table>\
        </div>",
        replace: true,
        scope: {
          treeData: '=',
          colDefs:'=',
          expandOn:'=',
          onSelect: '&',
          deleteContent: '&',
          editContent: '&',
          initialSelection: '@',
          treeControl: '='
        },

In addition, I have defined the following controller:

.controller('ContentCtrl', ['$http', '$scope', '$location', '$localStorage', 'authService', 'settings', function ($http, $scope, $location, $localStorage, authService, settings) {

  $scope.deleteContent = function(){
      console.log("delete");

    };
  }]);

Furthermore, I have included this view:

<tree-grid tree-data="policies"></tree-grid>

However, when I click on the delete link, nothing happens. It seems like it is not triggering the controller scope functions.

What could be causing this issue? Did I make a mistake somewhere?

I am aware that implementing the functions directly in the directive would be a workaround but not an ideal solution. How can I resolve this issue effectively?

Answer №1

To ensure the treeGrid directive can access the deleteContent, you must pass it through the template due to its isolate scope.

To rectify this issue, simply include the function when defining the directive in the template:

<tree-grid tree-data="policies" delete-content="deleteContent(branch)"></tree-grid>

The function has the ability to take any values defined on the current scope. In this case, it is taking branch. This value can be passed from the isolate scope by utilizing the following code snippet within the directive's template:

...
<td> <a ng-click=\"deleteContent({branch: row.branch})\" class=\"action\"><i class=\"glyphicon glyphicon-remove-circle\"></i></a> </td>\
...

Instead of solely passing the id, the entire branch is being passed in. This unique syntax is intended for directives that accept & isolate scope values and links the branch parameter (defined in the tree-grid directive) to the row.branch from the directive template. It is important to note that the property name "branch" inside tree-grid needs to correspond with the object used within the directive template (e.g. {branch: row.branch}).

For a visual representation of how deleteContent is passed to the directive, refer to this fiddle, which showcases logging to the console upon link click.

If the functionality remains static within the directive, an alternative approach would be to incorporate it into a link function:

Within the directive:

link: function (scope, element, attrs) {
   //...
   scope.deleteContent = function () {
       console.log("Content deleted");
   }
   //...
}

Answer №2

If you're looking to expand your knowledge on AngularJS events, some key terms to explore are $broadcast(name, args);, $emit(name, args);, and $on(name, listener);.

Here's a potential solution for your issue:

Controller:

.controller('ContentCtrl', ['$http', '$scope', '$location', '$localStorage', 'authService', 'settings', function ($http, $scope,       $location, $localStorage, authService, settings) {

    $scope.deleteContent = function(){
        console.log("delete");
        $scope.$broadcast('deleteContentEvent',yourParams...);
    };
}]);

Directive:

.directive('treeGrid', [
    '$timeout','$rootScope', function($timeout,$rootScope) {
     $rootScope.$on('deleteContentEvent',function(event,yourParams...){
         // perform delete action
     });
     ...

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

Updating controller variables when the route changes in AngularJS

I'm new to the AngularJS scene and I've encountered a challenge. My goal is to have the selected tab change dynamically based on the URL changes. Here's my JavaScript code: app.config(function($routeProvider, $locationProvider){ $rou ...

Implementing Enter key functionality to add items to a Todo list using pure DOM manipulation

var listLis=document.getElementById('list'); const addbutton=document.querySelector('.fa-plus') const inputBar=document.querySelector('.show') function showInput(e){ inputBar.classList.toggle('show') } addbutt ...

performing asynchronous iteration with HTTP PUT requests

I'm attempting to send multiple HTTP PUT requests to my server, but I am only able to successfully send one JSON object to the database. What could be missing in my code? var data1 = JSON.stringify(require('./abc.json')), data2 = JSON ...

Utilizing Javascript and CSS for horizontal alignment from left to right

I have a JavaScript function that generates a list of store locations and creates a DIV beneath the map. Currently, the items are displayed top to bottom on the page. However, I would like to change the layout so that the items are shown as 3 in a row fro ...

What is the reason behind JSLint's preference for x === "undefined" over typeof x == "undefined"?

I'm feeling lost when it comes to JSLint. Initially, my code checked if div:jqmData("me") was undefined in this way: if ( typeof el.jqmData("me") == "undefined" ? el.not(':jqmData(panel="main")').length > 0 : el.not(':jqm ...

Developing a Java Jersey web service that consumes JSON requests

I have developed a web service using Java and Jersey. The objective is to receive a JSON request, parse the JSON data, and save the values onto the database. Here is an excerpt from my web service code: @Path("companies") public class Companies { @P ...

Guide to adding and showing records without the need to refresh the webpage using CodeIgniter

Hey there! I've got a code snippet here for inserting and displaying records without refreshing the web page using AJAX and plain PHP. However, I'm not sure how to set this up using CodeIgniter. Can someone please lend a hand? Here's what I ...

Tips for displaying bar chart labels effectively with ChartJS

I am working on an Angular project and I would like to incorporate a barchart using ChartJS. The data for this chart can vary in size, sometimes being very large. One issue I have encountered is that when the number of data points is large, the labels ove ...

Storing information when an object is indexed in a for loop, to be retrieved later when

My JavaScript code includes an AJAX call that takes user input from a form and uses it to search for a JSON object. The matching objects are then displayed in a datalist successfully. Everything is working well so far, but now I want to extract specific f ...

Using axios with async/await to handle unresolved promises in Javascript

I'm facing a challenge with a piece of code I've been working on. Despite my efforts to find a solution online, I haven't had any success so far. Here is the code snippet in question: const fetchSidebarData = async () => { let da ...

ts-jest should replace the character '@' with the '/src' folder in the map configuration

I have set up a node project using TypeScript and configured various paths in my tsconfig.json file, such as: "paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl' ...

Text displaying as actionable icons

In my React project, I am utilizing material-table (https://material-table.com/#/) and have successfully imported the necessary icons. However, when viewing the action bar, the icons are displaying as plain text instead of the Material Icon. import React, ...

declaration of function interface and property that cannot be modified

After reviewing some new TypeScript code, I encountered a part that left me puzzled. interface test { (a: number): number; readonly b: number; } While I understand that (a:number): number signifies a function where the argument is a:number and the ret ...

Increasing the Efficiency of Styled Components

It appears to me that there is room for improvement when it comes to checking for props in Styled Components. Consider the following code: ${props => props.white && `color: ${colors.white}`} ${props => props.light && `color: ${c ...

What could be the reason for the malfunction of jQuery's show() function?

Using jQuery, I have implemented a functionality to hide a div using the hide() method. However, upon clicking a link, the div is supposed to show but unexpectedly disappears after appearing briefly. HTML Code Snippet <div id="introContent"> & ...

What is the best method to generate a distinct identifier for individual input fields using either JavaScript or jQuery?

I have attempted to copy the table n number of times using a for loop. Unfortunately, the for loop seems to only work on the first iteration. I am aware that this is due to not having unique IDs assigned to each table. As a beginner, I am unsure how to cre ...

Bootstrap form validation issues

Currently, I am utilizing Vue.js along with Bootstrap for the creation of a website. In this process, I have set up a form on which I am implementing my custom validation logic. Everything seems to be functioning correctly until the moment when the user hi ...

Exploring the nuances in semantics between AJAX and post/get requests

I'm currently trying to grasp the concept of 'AJAX.' I know that it is short for Async JavaScript over XML, although JSON can also be used instead of XML. As far as I understand, AJAX allows for updating only parts of a web page without need ...

Retrieve information from the API prior to rendering the controller components

Hello there! I am looking to retrieve data from a factory before any of my controllers are loaded. After some research, I discovered that it can be achieved using the resolve function in AngularJS: angular.module('agent', ['ngRoute',&a ...