Communication between AngularJS directives and controllers occur when a function is called upon a change

I have developed a unique custom directive which is defined as:

<div class="col-md-6">
    {{templateMapping[colProp].SheetPointer}}
    <select class="form-control"
        ng-model="selectedColumn"
        ng-change="changeMapping()"
        ng-options="Col.SheetPointer for Col in optionList"></select>
</div>

Take note of the ng-change.

The code for my directive implementation is as follows:

angular
.module('app.import')
.directive('mappingEdit', ['$rootScope', function ($rootScope) {
    return {
        restrict: "E",
        templateUrl: "partials/templates/MappingEdit.html",
        scope: {
            templateMapping: "=", //parent object
            colProp: "@", //name of property
            optionList: "=",
            colFilter: "=filter"
        },
        link: function (scope) {
            scope.selectedColumn = {};
            scope.changeMapping = function() {
                // The ng-change event triggers here!
                scope.templateMapping[scope.colProp] = scope.selectedColumn;
                // Call "autoSave" here, remember that the "commitSave" function is in the Controller...
            };
        }
    }
}]);

To use this custom directive, you can do so like this:

<mapping-edit 
    template-mapping="mapping" 
    col-prop="MappedColumn" 
    option-list="columnList" 
    filter="selectedSheet.SheetName" />

Notice that my directive's HTML code consists of a <select> element and incorporates an ng-change event. I aim to invoke a function from my controller named commitSave, which is structured as follows:

$scope.commitSave = function () {
    alert("on changed!")
}

What method would enable me to call this controller function from within my directive using the ng-change event?

Answer №1

There are two ways to achieve this.

  1. One way is to pass the function in the scope definition like so:

        scope: {
            templateMapping: "=", //parent object
            colProp: "@", //name of property
            optionList: "=",
            colFilter: "=filter"
            updateFn: "&"
        },
    

    In your markup, it would look like this:

    <mapping-edit 
    template-mapping="mapping" 
    col-prop="MappedColumn" 
    option-list="columnList" 
    filter="selectedSheet.SheetName" 
    updateFn="commitSave"/>
    

    Finally, in your link function:

    scope.changeMapping = function() {
            // ng-change fired here!
            scope.templateMapping[scope.colProp] = scope.selectedColumn;
            scope.updateFn()
        };
    
  2. Alternatively, you can use events :)

You can see a demonstration in this Plunker from the angular docs: http://plnkr.co/edit/UTPVE1qeTraJZcWRK1UO?p=info

Answer №2

There is a possibility to include an additional attribute for passing the controller function into the directive scope

<mapping-edit 
    template-mapping="mapping" 
    col-prop="MappedColumn" 
    option-list="columnList"
    commit-save ="commitSave" 
    filter="selectedSheet.SheetName" />

JavaScript

angular
.module('app.import')
.directive('mappingEdit', ['$rootScope', function ($rootScope) {
    return {
        restrict: "E",
        templateUrl: "partials/templates/MappingEdit.html",
        scope: {
            templateMapping: "=", //references parent object
            colProp: "@", //defines property name
            optionList: "=",
            colFilter: "=filter",
            commitSave : '=' // binds to controller function
        },
        link: function (scope) {
            scope.selectedColumn = {};
            scope.changeMapping = function() {
                // ng-change event occurs here!
                scope.templateMapping[scope.colProp] = scope.selectedColumn;
                // call "autoSave" function
                scope.commitSave( /* parameters */ )

            };
        }
    }
}]);

Answer №3

Integrate a new directive feature similar to AngularJS API called on-change:

<mapping-edit 
   template-mapping="mapping" 
   col-prop="MappedColumn" 
   option-list="columnList" 
   on-change="commitSave()"
   filter="selectedSheet.SheetName" />

Invoke that function within changeMapping:

scope.changeMapping = function() {
   // Execute ng-change functionality here!
   scope.templateMapping[scope.colProp] = scope.selectedColumn;
   // Trigger the on-change event here!
   $parse(attrs.onChange)(scope);
};

Ensure to include the service dependency for $parse

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

Adjustable Pop-up Modal

I am attempting to implement a resizable modal window feature by utilizing increase and decrease icons. Additionally, I aim to have the modal centered on the screen following each click of increase/decrease. Thus far, only the increase functionality is fu ...

issue with splice function

I have a JavaScript function that is supposed to collect all input values from text boxes and store them in an array. However, I want to remove any input value with the type "button" from the array before proceeding. Here is the code snippet: <!-- lang ...

Create a separate server session specifically for handling an ajax request?

Currently, I am working with a collection of PHP server-side scripts that manage user session state by utilizing PHP sessions extensively for authenticated users. For the client side within a mobile application and using Jquery ajax, I am striving to esta ...

Using Node/Express to split the request headers with the .split() method

I am currently working on a way to determine if a specific item exists in the req.headers in order to make a decision on what to send back to the user. Here is my code snippet: function serveAppData(req, res) { console.log("CHECKME", req.headers); //var h ...

Creating a multi-filter gallery similar to the one found in WooCommerce or eCommerce platforms involves integrating various filters to allow

Looking for a dynamic multifilter gallery similar to WooCommerce/ecommerce product filters? We have three types of filter dropdowns: COLOR, SIZE, and SHAPE. For example, if you select color: red and green, size: small, and shape: round The filtering wil ...

Self-reference within a JavaScript object involves creating a property that points

Can you reference another part of a JSON object within the same JSON object? In the code snippet below, there is an object that refers to the "home" object within the "MapParameters" object. { "parameters": { "data": { "URL": "http://SC.json ...

Updating the parent controller's scope from a directive in AngularJS does not reflect changes

HTML: <div ng-app="myApp" ng-controller="Controller"> <test ng-if="toggle" props="condition"></test> </div> Javascript: var myApp = angular.module('myApp', []); myApp.controller('Controller', ['$scop ...

Transforming Javascript code using regular expressions into C#

Currently, I am facing a challenge while trying to translate some Javascript code into .NET. Despite my efforts, I have not been able to get it right. The task at hand involves converting paths like /test/:value1/:value2 in Express for NodeJS to a regular ...

Obtaining the complete JSON array in string format

I am currently using Fine Uploader to pass parameters in this way callbacks: { onSubmit: function(id, fileName) { this.setParams({ a: 'adm', b: '126', c: { fileID: id, ...

Receiving CORS response from the server for just one of the two API calls

Description of the issue: I am facing a peculiar problem where I am encountering different responses while making two calls to the same API. One call is successful, but the other returns a 504 error. Access to XMLHttpRequest at '' from orig ...

What is the best way to update the switchery checkbox after it has already been initialized?

I have set up the switchery using the code snippet below. var ss_is_schedule_edit = document.querySelector('.ss_is_schedule_edit'); var mySwitch = new Switchery(ss_is_schedule_edit, { color: '#8360c3' }); However, I am unable to toggle ...

What is the method for attaching multiple listeners to an element?

For example: v-on:click="count,handle" I posted this question in the Vue gitter channel, but received advice to use a single listener that triggers others. If using one listener is the recommended approach, I am curious to understand why. Is having multi ...

Surprising Media Component Found in URL Parameters within the design

Exploring the page structure of my Next.js project: events/[eventId] Within the events directory, I have a layout that is shared between both the main events page and the individual event pages(events/[eventId]). The layout includes a simple video backgro ...

Incorporate a video within the royal slider feature

Next is my deluxe slider code. This slider displays only images but I am looking to incorporate video as well. I have searched online and tried different solutions, but haven't found one that works for me. Can someone please guide me on how to achieve ...

Acknowledging client after client to server POST request has been successfully processed in Node.JS

I've been working on responding to client-side requests with Node.JS. While searching, I came across a helpful article on calling functions on the server from client-side JavaScript in Node JS. However, I'm having trouble implementing it in my pr ...

Can the title of a page be modified without using HTML?

Is it possible to update the title of my website directly from the app.js file? (I am utilizing node.js and express.js) ...

React setState issue experienced only on initial click due to API lag

My goal is to develop a web app using the Poke API to display multiple Pokemon. I have added buttons to allow users to "change the page" and switch the API URL to view the next or previous set of Pokemon. However, I'm facing an issue where the buttons ...

Combining various FormGroup types into a single object type in Angular 5

I am currently utilizing the mat-stepper feature from the Angular Material design library. Within my application, I am using 3 separate FormGroups to gather information and send it to a database using the httpClient method. To achieve this, I have defined ...

Load JavaScript files in order within the <body> tag and trigger a callback function when all files have

Currently, my website (which is actually a Cordova/Phonegap app) has the following scripts in the <head>: <script type="text/javascript" src="cordova.js"></script> <script type="text/javascript" src="appPolyfills.js"></script> ...

Implementing click events to control GSAP animations in Next.js

I'm having trouble figuring out how to pause/start an animation using GSAP in Nextjs. Specifically, I can't seem to work with a tl.current outside the useEffect hook within this component. My goal is that when I click on the first .imgWrapper ele ...