Observing a two-way binding in AngularJS directive with the $watch functionality

I am currently working on differentiating between internal changes and external changes using a two-way data-bound attribute ('=').

To clarify: I want to prevent $watch from triggering if the change was made internally (such as altering the scope variable in the controller or link function).

Here is some code that highlights my issue:

HTML

 <div ng-app="myApp">         
   <div ng-controller="MainCtrl">
     <input ng-model="value"/>
     <mydemo value="value"></mydemo>
  </div>
 </div>

Javascript

app.directive('mydemo', function () {
  return {
    restrict: 'E',
    scope: {
      value: "="
    },
    template: "<div id='mydiv'>Click to change value attribute</div> Value:{{value}}",

    link: function (scope, elm) 
    {      
      scope.$watch('value', function (newVal) {
      //Ignore changes from the changeValue function
      //Listen for changes from the input element 
      });
      // Implement any model syncing here.

      var changeValue = function()
      {
        scope.$apply(function ()
        {
          scope.value = " from changeValue function";
        });
      }

      elm.bind('click', changeValue);
    }
  }
})

Live demo: http://jsfiddle.net/B7hT5/11/

Any suggestions on how I can make this distinction?

Answer №1

There is no built-in feature that differentiates between these two events, so you will need to handle that behavior yourself.

One way to do this is by setting a flag whenever a change is made "internally," and then checking for it in the watch function.

Here's an example:

link: function (scope, elm){      

  var internal = false;

  scope.$watch('value', function (newVal) {
    if(internal) return internal = false;
    // Add your code here to run on external changes.
    console.log(newVal);
  });

  var changeValue = function(){
    scope.$apply(function (){
      internal = true; // set the internal flag
      scope.value = " from changeValue function";                              
    });
  }

  elm.bind('click', changeValue);
}

Check out the revised fiddle.

Another approach could be creating a custom directive using the ngModel API to differentiate between DOM -> Model (external) and Model -> DOM (internal) changes. However, it may not be necessary in this case.

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

What is the best way to adjust the size of an image within a div element using HTML?

I've created a Carousel with 5 images to display. However, I'm having an issue where only the image is showing up, and I want the text and button to appear below it. Here's how the nature image is currently displaying: What I want is for th ...

Using JQuery to dynamically add a third expandable row to a table

In my JQuery code (within documentReady), I utilize DataTable to create a table. table = $('#transaction').DataTable({ "ajax": { "url": "servicingTransactionsLoad.do", "type": "GET", " ...

"Using Node.js for proxying requests and implementing OAuth authentication

Having a small node.js application that relies heavily on oAuth, I encountered an issue: the server where I intend to install it is concealed behind a proxy. This necessitates rewriting a portion of the code to incorporate proxy usage. Here's my query ...

Attempting to send numerous identifiers in an API request

I encountered a problem while working on a function in Angular that involves pulling data from an API. My goal is to enhance a current segment to accommodate multiple IDs, but I face difficulties when attempting to retrieve more than one ID for the API que ...

A guide on incorporating a React custom package within an Angular directive

Hey there, I have an Angular v1.x application and a React custom package. I'm looking to integrate the React custom package into my Angular directive, so that it can display a React component. Here's some code snippet: Angul ...

Expanding Option Select in AngularJS with Additional Values

As I work on my AngularJS application, The Goal: I aim to enable users to choose an address from a dropdown menu and pass this data to the next step. Current Challenges: I need to show limited data per address option - House Number, Street ...

Querying MongoDB to filter data using multiple conditions simultaneously

How can MongoDB be used to filter documents based on multiple fields and value types? In my dataset, I have documents with different fields that I want to use as filters to retrieve specific documents. For example: The Person field can have values like ...

Establishing a path for a post request in a Node.js application

While setting up a basic registration page, I encountered an error when trying to establish a route for the post request of the user credentials. node:_http_outgoing:648 throw new ERR_HTTP_HEADERS_SENT('set'); ^ Error [ERR_HTTP_HEADERS_ ...

Utilizing Vue.js for enhanced user experience, implementing Bootstrap modal with Google Maps autocomplete

I recently set up a Bootstrap modal that includes an <input>. To enable Google autocomplete for it, I utilized the commonly known trick below: .pac-container { z-index: 10000 !important; } However, I have encountered difficulty in getting the a ...

AngularJS directive that allows for either a click action to be passed or a ui-router state change to

I have a button (an a tag) that is displayed in multiple locations on my website. It is labeled "View Demo", and sometimes it directs to a demo page using an ui-sref: <a class="btn btn-primary" ui-sref="hamburger-push" target="_blank"> View Demo ...

The transitions on my jQuery Mobile page are not functioning correctly

I am currently working on a custom MVC structure using Handlebars and jQuery Mobile. To manually manage routing, I have disabled two jQM parameters: $.mobile.linkBindingEnabled = false; $.mobile.hashListeningEnabled = false; These lines disable link bind ...

Animating the first element using Semantic UI React Transition Group

Is there a way to modify Semantic's Transition.Group example (found at ) to animate the topmost element instead of the bottommost one? In the example provided, pressing the add or subtract button results in the animation applying only to the last ele ...

Oops! The useNavigate() function can only be utilized within the confines of a <Router> component

I encountered an error while working on my project: An uncaught Error occurred: useNavigate() may only be used within a context of a <Router> component. at invariant (bundle.js:36570:20) at useNavigate (bundle.js:36914:35) at App (bundle. ...

Send data to a JavaScript file

Even though this particular question has been asked and answered multiple times, I am still struggling to find a solution to my problem. I am currently working with Masterpages and JavaScript files, and as many people are aware, Masterpages can be quite t ...

Troubleshooting the Nextjs-blog tutorial loading issue on localhost:3000

Looking to delve into Nextjs, I decided to start by following a tutorial. However, every time I attempt to run 'npm run dev', the local host just keeps loading endlessly. Upon inspecting and checking the console, there is no feedback whatsoever. ...

Axios delivers the index.html data to the front end of a React.js application

I’m currently in the process of developing a web application using React.js for the front-end and Flask for the back-end. I attempted to establish a connection between the two by defining a proxy server in React and enabling CORS in Flask. Everything was ...

I'm surprised by the fact that array.findIndex is not functioning properly. According to Mozilla, it should be working fine

It was necessary to change state.findIndex to state.ids.findIndex in order to resolve the issue I was facing. However, an unexpected behavior occurs when calling the function onClick, as it automatically updates ALL of the active values to true, instead o ...

Display the contents in a textarea with modal, not as a string

I'm currently working on implementing a modal overlay window with simplemodal that will display the contents of a text area. My goal is to show the rendered output rather than just the string value. For example, if a user enters HTML or includes an im ...

Unending loop caused by nested subscriptions - Angular / RxJS

I am currently implementing a nested subscribe operation, although I am aware that it may not be the most efficient method. Here is an example of what I have: this.route.params.subscribe((params) => { this.order$ .getMa ...

Getting files from a server in ReactJS: Step-by-step guide

Currently, I am utilizing an API to retrieve file paths from the server. However, I am looking to enhance the functionality by allowing users to download these files upon clicking on them. To achieve this, I am leveraging the react js-file download package ...