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

Develop a novel function

I am working on a new Order page where users can select a category, then a service, and fill out the quantity field for their order. I have an idea to create a function using @if and @else statements. In this function, I want to display the quantity fiel ...

Axios removes the async functionality

Is there a way to achieve the same functionality without using the async function? async EnvioLogin() { const response = await axios.post("api/auth/login", { email: this.email, password: this.password, }); localStorage.setItem(" ...

Updating the state value of a variable that utilizes a custom Hook: a step-by-step guide

After watching a video by Dan Abramov, I decided to optimize my component by creating a custom Hook called useFormInput. This hook handles the state and onChange functionality for all of my form input fields. Everything was working perfectly until I neede ...

"Dealing with an unspecified number of fields in an ExtJS data model

I have a data model that is designed to accommodate various incoming data by keeping it generic and allowing for the addition of multiple meta data tags to my project. How can I effectively map these data fields to the Model or access them in the array w ...

angular table disabled based on condition

I have a table in my HTML file and I am trying to figure out how to disable the onClick function if the start date is greater than the current date. <ng-container matColumnDef="d"> <th mat-header-cell ...

Using an id as the attribute value for a React ref

I have a question about referencing DOM nodes in a component. Currently, I am able to get the nodes and children using the following code: export class AutoScrollTarget extends React.Component { constructor(props) { super(props); this ...

Material UI offers a feature that allows for the grouping and auto-completion sorting

I am currently utilizing Material UI Autocomplete along with React to create a grouped autocomplete dropdown feature. Here is the dataset: let top100Films = [ { title: "The Shawshank Redemption", genre: "thriller" }, { title: " ...

Utilizing Data From External Sources in a React Application

I have encountered an issue with displaying data from another page in a reusable table I created using React. Specifically, I am having trouble getting the value to be shown in <TableCell> Please check out this code sandbox link for reference ACCES ...

Failed to validate user profile because of an InternalOAuthError error while using passport-facebook-token to verify the token

In my iOS application, I am utilizing the Facebook API for user login and receiving an access token in return. Now, I need to use this token to verify a user on my backend server. For this purpose, I have implemented the passport-facebook-token strategy w ...

Encountering issues with accessing image files located in the public folder of my Next.js project - Receiving a 404 Error message

I am currently facing an issue with my Next.js project where I am unable to use image files from the public folder. Despite checking that the file paths, names, and extensions are correct, as well as ensuring my configurations are accurate, I keep encounte ...

Modifying an image's src using JavaScript is not possible

I'm attempting to modify the source of an image using a JavaScript function, but it doesn't seem to be working. The function is being executed within a mounted() method in Framework7. Here is my current setup: HTML: <div> <span> &l ...

Implementing initial state checks for Alpine.js checkboxes based on x-modal is not functioning properly

Upon loading alpinejs, for some reason all checkboxes become unchecked. It's perplexing and I can't figure out why. <div x-data="{ colors: [orange] }"> <input type="checkbox" value="red" x-model="co ...

How can Backbone.js utilize Ajax to bind data to a Collection?

I've recently delved into the world of Backbone.js. My goal is to create a Collection and populate it with data sourced externally. The current format of the data is CSV, not JSON. I am considering converting it to JSON for simplicity. Therefore, I ...

Having trouble passing multiple associative array values from JavaScript/AJAX to PHP

We have been encountering an issue when trying to pass multiple associative array values from JavaScript/AJAX to PHP, as the PHP file is receiving an empty object/array. Could someone kindly assist us in retrieving the values of an associative array from ...

Child element casting shadow over parent element

I am currently using box shadow for both the parent (.map) and child (.toggle-button): .map { position: fixed; top: 20px; right: 0; width: 280px; height: 280px; z-index: 9999; box-shadow: 0px 1px 6px 0px rgba(0,0,0,0.3); } .map ...

Set the background color of the Material UI Drawer component

Need some advice on changing the background color of Material UI's Drawer. I've attempted the following approach, but it's not producing the desired result. <Drawer style={customStyle} open={this.state.menuOpened} docked={false} ...

A guide on triggering a function when a button is clicked in reactjs

Can anyone please help me with this issue I'm having: how do I execute a function when a button is clicked? I currently have the following code but it's not working export var Modulo = React.createClass({ prom1: function () { retur ...

The onBlur() method is not functioning properly in JavaScript

Created a table using PHP where data is fetched from a MySQL database. One of the fields in the table is editable, and an onBlur listener was set up to send the edited data back to the MySQL table. However, the onBlur function doesn't seem to work as ...

javascript alter css property display to either visible or hidden

I am struggling with a CSS id that hides visibility and uses display: none. The issue arises when I want the element to be visible upon clicking a button, but removing the display:none property is causing design problems due to it being an invisible elemen ...

Delivery person receiving biscuit but my internet browser doesn't seem to be getting it when I attempt to retrieve it

Currently, I am in the process of creating a website using Flask and React. The user is required to input an email and password on a form, which is then sent via axios.post to the backend. The backend checks if the email and password match with the databas ...