AngularJS: Service variable not triggering $watch when updated within a directive's call

When I modify the service variable using a controller function, the $watch is triggered. However, it does not trigger when the same variable is changed by a directive.

<html>  
<head>
<meta charset="UTF-8"> 
    <script src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script>
    <script> 
        var mainApp = angular.module('mainApp', []);    


        mainApp.service ("service1", function () {
            this.x = 0
            this.add = function () {
                this.x += 1;
            }
            this.display_x_value = function () {
                alert (this.x)
            }
        })



        mainApp.controller ( 'c1', function ($scope, service1) {

            ///////     Add 1 to service1.x 
            $scope.add = function () {
                service1.add ();    
            }

            //////      display the value of service1.x 
            $scope.display_value = function () {
                service1.display_x_value ();    
            }

            /////       watch service1.x
            $scope.$watch ( function () {
                return service1.x
            },
            function  (newVal, oldVal, $scope)  {
                alert ("watch has triggered :   " + newVal)
            }, true )


        });





        mainApp.directive ("testDirective", function (service1) {
            return {
                link: function ($scope, element, attrs) {
                    element [0].onclick=function () {
                        service1.x = service1.x + 2000
                    }
                }

            }
        })


    </script>

</head>
<body ng-app="mainApp" ng-controller="c1">  
    <button ng-click="add ()">change service1.x    BY CONTROLLER</button>
    <button test-directive> change service1.x   BY DIRECTIVE  </button>
    <button  ng-click="display_value ()"> display service1.x </button>

</body>
</html> 

The directive actually changes the variable, as indicated by the output of service1.display_x_value. Interestingly, calling this function causes $watch to trigger if the variable was modified previously.

I attempted to alter the variable by invoking the controller function in the directive, but that did not produce any results:

mainApp.directive ("testDirective", function (service1) {
            return {
                link: function ($scope, element, attrs) {
                    element [0].onclick=function () {

                        $scope.add ()
                    };


                }
            }
        })

Answer â„–1

When a click event does not trigger the digest cycle, you can manually invoke it using $scope.$apply().

    mainApp.directive("testDirective", function(service1) {
        return {
            link: function($scope, element, attrs) {
                element[0].onclick = function() {
                    service1.x = service1.x + 2000;
                    $scope.$apply();
                }
            }

        }
    })

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

Step-by-step guide to tweeting with Codebird PHP from a pop-up window

I want to enhance the visitor experience on my website by allowing them to easily post a tweet with an image directly from the site. To achieve this, I have implemented the Codebird PHP library. While everything is functioning correctly at the moment, ther ...

What is the best way to create a moving line using EaselJS and TweenJS?

My objective is to animate a line from point A to point B using the Tween function. I am utilizing the EaselJS drawing library and TweenJS for animation. Can I achieve this by using the moveTo function to animate a straight line from point A to point B? ...

Experiencing a [$compile:multidir] error when attempting to implement a multiselect dropdown with Angular.js

I encountered an issue when utilizing a multi-select drop-down list in Angular.js. Error: angularjs.js:107 Error: [$compile:multidir] http://errors.angularjs.org/1.4.6/$compile/multidir?p0=ngDropdownMultiselec…22%20checkboxes%3D%22tr ...

Adding external JavaScript files that rely on jQuery to a ReactJS project

As a beginner in web development, I have a question regarding importing external JavaScript files in ReactJS. I currently have the following imports: import $ from 'jquery'; window.jQuery = $; window.$ = $; global.jQuery = $; import './asse ...

Animated mosaic pattern menu design

Is there a way to achieve this effect with a sketch? Note: I would like to add hover animation to the borders if possible. I attempted to do it using the following code: clip-path: polygon(0 0, 100% 0, 92% 86%, 6% 100%); However, the shapes created by ...

Looping through multi-dimensional JSON objects with jQuery

Hello there, I'm currently facing some challenges in getting the screen below to work properly: Project progress screen I have generated the following JSON data from PHP and MYSQL. My goal is to display the project alongside user images and names whe ...

Is there a way to search for multiple items using just one search term?

On my app, there is a search bar that currently only looks up data for one specific attribute. For example, if I type in "Hammer," it only searches for Tool names. Now, I need to expand the search functionality to accommodate different types of strings. F ...

JavaScript transform numbers into array of buffers with a length of 4

I'm looking for a way to insert a numerical value into an array of 4 values [uint32_t] For example 255 should look like [0x00, 0x00, 0x00, 0xFF] I need to transmit this value from a Node.js server to an Arduino board Is there a built-in solution or ...

Substitute the string (3-11-2012) with a different date layout (3 november 2012)

Can anyone guide me on how to convert text strings like '11-1-2012' into date strings like '11 januari 2012'? I've been looking for a solution, but haven't found exactly what I need. The month names should be in Dutch. I attem ...

sending arguments to a function within ng-show

How can I properly call a function with a parameter in ng-show without errors? I encountered the error Error: [$parse:syntax] Syntax Error: Token ']' not a primary expression at column 8 of the expression [cheked[]] starting at []]. The parameter ...

"What is the best approach to adjusting the width of one div based on the width of another div using CSS Grid

As a beginner in programming, I'm trying to work with CSS Grid but facing some challenges. My goal is to create a component with two columns: the left column should have a width of minmax(570px, 720px), and the right column should be minmax(380px, 10 ...

Create a Javascript dropdown menu with a validating calendar picker

My webpage has a drop-down menu that is dynamically generated via .jsp and filled with data from a database. However, I am having trouble with a JavaScript validation for two drop-down fields and two date pickers. Despite my limited JavaScript skills, I ne ...

Finding all elements with a specified attribute in jQuery: A comprehensive guide

While looking for an example, I came across one that searches only inputs instead of all elements: https://api.jquery.com/attribute-equals-selector/ Is there a way to modify this example so that it can search all elements in the DOM, and not just inputs ...

How can I limit the keys in a Typescript object to only certain strings?

Is there a way in Typescript to create an object of type Partial with keys that can only be a combination of 'a', 'b', or 'c'? The object should not have all 3 keys, but it must have at least one. Here's what I've at ...

What is the alternative to using document.getElementById?

1) Question 1 Why does the following example work without using "document.getElementById('myId')" and is it acceptable to skip this step? <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Javascript quest ...

jQuery breaks when a new class is added to 'Overlay transparent image'

I came across a helpful script HERE that allows me to overlay a transparent image over photos on my website for protection. I want to be able to make images with hyperlinks accessible by giving them a special class. Below is the original script: <scri ...

How can I implement a feature to automatically close a drawer in a React application using the Material UI

Currently, I am utilizing a React material design theme However, I am facing an issue where the drawer navigation button on mobile view does not close automatically upon clicking I need something like (onClick={handleClose}) to resolve this problem Does ...

Automating the process of posting a file to a form with javascript

I have a piece of client-side JavaScript that creates a jpeg file through HTML5 canvas manipulation when the user clicks an "OK" button. My goal is to automatically insert this jpeg output into the "Upload Front Side" field in a form, simulating a user up ...

How can I apply a CSS class to a group of radio buttons within a radio button list?

I'm attempting to validate a radio button group and apply a specific CSS class to it. Since this is a server control, I can only apply the class one way. However, upon checking with jQuery, I discovered that the class is actually being attached to the ...

The function '$.fn.<new_function>' is not a valid function in jQuery

UPDATE: code link with enhanced formatting: UPDATE: code upgraded with enhancements from JSHint http://pastebin.com/hkDQfZy1 I am attempting to utilize $.fn to establish a new function on jQuery objects by this method: $.fn.animateAuto = function(x,y) { ...