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

Ensuring the integrity of forms and validating inputs in Angular

Creating a form for adding or editing users has its own set of challenges. When the page loads with existing data in formData, it indicates that an existing user is being edited and the fields need to be populated accordingly. On the other hand, if the pa ...

Unlock the Power of Vue Draggable in Vue.js 3 with These Simple Steps

When attempting to implement Draggable in Vue.js 3, I encountered an error message: VueCompilerError: v-slot can only be used on components or <template> tags. Below is a snippet of my code: <draggable tag="transiton-group" name="s ...

Internet Explorer 10 not triggering the 'input' event when selecting an option from the datalist

Within this particular scenario, there is an input field paired with a corresponding datalist element. My aim is to develop JavaScript code that actively listens for when a user chooses an item from the list. Most resources suggest utilizing the "input" ev ...

Discover the magic of observing prop changes in Vue Composition API / Vue 3!

Exploring the Vue Composition API RFC Reference site, it's easy to find various uses of the watch module, but there is a lack of examples on how to watch component props. This crucial information is not highlighted on the main page of Vue Composition ...

The issue with the callback function not being triggered within a self-repeating loop

As I work on creating a user-script to incorporate a trailer video into a website, I encountered an issue with the callback function in my script. The goal is to filter the real source of the video from different URL formats, but for some reason, the callb ...

Saving Selected Radio button values into Jquery Array

In my HTML table, there are multiple rows with radio buttons representing the sexes in the 0th position of <td>. I am trying to store the values of sex (either 1 or 0) in an array. Below is a snippet for a table with 3 rows. HTML Code: <table> ...

Stopping autoplay in Swiper as soon as you hover over it

My swiper is set to autoplay, but I want it to stop immediately when hovered over instead of waiting for the transition to finish. Is there a way to interrupt the transition and stop it at the exact point where the cursor hovers? Here is my Swiper config ...

Locating a Guild Member using their Alias

I need help locating a GuildMember using their nickname. The nickname is linked to their Roblox name upon joining the server, and I've configured a webhook to transmit a message in a specific channel containing their username and other related details ...

Obtain the values from controls within the <td> element

I'm experiencing some difficulty creating an array of table cell values because the cells contain controls, not just plain text. $("#tbl_CGT tr").each(function() { var arrayOfThisRow = []; var tableData = $(this).find('td'); if (tab ...

Tips for effectively reusing the modal component in Vue.js without encountering re-render issues

I'm encountering an issue where the same component content is being rendered despite having different components (Rendering problem). I have a reusable modal component called modal.vue, so every time I create a new component, I call the modal compone ...

Switch between different react components

When a component is opened, I want all other components to close. Whenever they are clicked, they will display a list. class ParentComponent extends Component{ constructor(props){ super(props) this.state= {...} } render(){ return( ...

Analyze the length of time and provide a percentage of similarity

Is it possible to compare two durations and calculate the percentage of similarity? Suppose I have a reference duration, as well as a second duration that needs to be compared with the first one. There is an 8% tolerance level, meaning that the second du ...

Organize angularjs ngRepeat with updated data outcomes

I am facing a situation where I need to display results from different ajax sources, but they are loaded asynchronously. The problem is that I want the results to be sorted alphabetically once they are all loaded. ngRepeat doesn't sort them correctly ...

How can I dynamically update an img src using JavaScript on a PHP webpage?

I have a PHP page where I display image thumbnails. I am trying to implement a feature where the thumbnail expands in another image on mouseover. Here is the PHP code snippet: echo "<tr><td><a href='$imgrow[location]' target=&ap ...

Issues with $state.includes in AngularJS ui-router when dealing with states that have default parameters - a conundrum?

Whenever I use $state.includes('courses.all({ clientType: "organizations" })') it results in undefined However, it does work with just $state.includes('courses.all') The parameter clientType is optional here and defaults to 'o ...

Using jQuery to reference my custom attribute---"How to Use jQuery to reference My

Can you explain how to reference a tag using a custom attribute in jQuery? For example, if I have a tag like this: <a user="kasun" href="#" id="id1">Show More...</a> I want to reference the tag without using the id. So instead of using: $( ...

CSS- Strategically placing and centering images above specific keywords in (any) HTML content without disrupting the flow of text

My main objective involves dynamically inserting images above text on any given page using a content script. The challenge lies in maintaining the proper alignment of the text after adding the images. To achieve this, I surround the words where the image i ...

Is there a way to automatically zoom in when clicking on a marker and centering the map to that

I have integrated a map into my project where I am currently plotting random coordinates. These coordinates are stored in a data table and everything is functioning smoothly. However, I am facing an issue with implementing a zoom feature using the panTo m ...

Once it hits the fourth tab, it must not cycle back to the first one

Hi there, I'm new to JavaScript I noticed that when I click the left and right arrows, the tabs circle back to the beginning However, I would like the circle to stop. When it reaches the fourth tab, it should not go back to the first. This should also ...

difficulty with parsing JSON in jQuery when referencing an external file containing the same data

Looking for help with parsing a json file using jquery? Check out this working sample: http://jsfiddle.net/bw85zeea/ I'm encountering an issue when trying to load "data2" from an external file. The browser keeps complaining that it's an invalid ...