Executing a function within the link from a controller in an angular directive with Angular JS

I recently developed a custom directive that includes both a link and controller. Here is the code snippet:

  var delightMeterApp = angular.module('delightMeterApp', []);
    delightMeterApp.directive('delightMeter', function () {

        function link($scope, $element, $attrs) {
            // Custom DOM manipulation logic here
        }

        return {
            scope: {
                score: '=ngModel'
            },
            restrict: 'E',
            templateUrl: 'svgmeter.html',
            link: link,
            controller: 'delightMeterController'

        };
    });


    delightMeterApp.controller('delightMeterController', function ($scope) {
        $scope.delightScore = 0;
    });

In my project, I need to call the `ScoreRotateNeedle` function, which is located within the directive's link, from the controller. This function should be triggered on the `ng-change` event in the HTML file as shown below:

<div ng-controller="delightMeterController">
    <delight-meter ng-model="delightScore"></delight-meter>
    <input id="txtScore" type="text" ng-model="delightScore" />{{delightScore}}

</div>

However, it is not recommended to include DOM manipulations inside controllers. Therefore, I am looking for ways to move this function out of the controller and potentially into the directive's link function or another suitable location. Any suggestions on how to achieve this? Should I consider using a service instead?

Update:

<div id="delightmeter">

    <svg width='500px' height='300px' version='1.1' xmlns='http://www.w3.org/2000/svg'>

        <g>
            <text x='100' y='220' fill='black'>0</text>
            <text x='300' y='220' fill='black'>100</text>
            <path class='arc' id='arc1' d='' />
            <path class='arc' id='arc2' d='' />
            <path class='arc' id='arc3' d='' />
            <path class='arc' id='arc4' d='' />
            <path class='arc' id='arc5' d='' />
            <g class='needleset'>
                <circle class='needle-center' cx='200' cy='200' r='5'></circle>
                <path class='needle' d='M 195 198 L 200 100 L 205 202'></path>
                <circle class='needle-center' cx='200' cy='200' r='5'></circle>
            </g>
        </g>

    </svg>

</div>

Answer №1

Implement this code snippet in your project:

HTML:

<div ng-controller="delightMeterController">
    <delightmeter ng-model="delightScore"></delightmeter>
    <input id="txtScore" type="text" ng-model="delightScore" />{{delightScore}}

</div>

Directive:

    .directive('delightmeter', function () {
    function link($scope, $element, $attrs) {

        var meter = $element[0];
        console.log(meter);

        document.getElementById("arc1").setAttribute("d", describeArc(200, 200, 100, -90, -56));
        document.getElementById("arc2").setAttribute("d", describeArc(200, 200, 100, -54, -20));
        document.getElementById("arc3").setAttribute("d", describeArc(200, 200, 100, -18, 16));
        document.getElementById("arc4").setAttribute("d", describeArc(200, 200, 100, 18, 52));
        document.getElementById("arc5").setAttribute("d", describeArc(200, 200, 100, 54, 90));

        function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
            var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0;

            return {
                x: centerX + (radius * Math.cos(angleInRadians)),
                y: centerY + (radius * Math.sin(angleInRadians))
            };
        }

        function describeArc(x, y, radius, startAngle, endAngle) {

            var start = polarToCartesian(x, y, radius, endAngle);
            var end = polarToCartesian(x, y, radius, startAngle);
            var arcSweep = endAngle - startAngle <= 180 ? "0" : "1";
            var d = [
                "M", start.x, start.y,
                "A", radius, radius, 0, arcSweep, 0, end.x, end.y
            ].join(" ");
            return d;
        }

        function ScoreRotateNeedle(delightScore) {

            $('.needleset').css({
                "transform": "rotate(" + delightScore + "deg)",
                "transform-origin": "50% 95%"
            });
        }

        $scope.$watch('score', function() {
            ScoreRotateNeedle($scope.score);
        });
    }
    return {
        restrict: 'E',
        templateUrl: 'components/comp01/comp01.html',
        scope: {
            score: '=ngModel'
        },
        link: link
    };
})

Controller:

.controller('delightMeterController', function ($scope) {

    $scope.delightScore = 0;

})

Answer №2

To enhance the functionality, I suggest eliminating the scope: true, and connecting the function directly to the scope.

Answer №3

Make sure to utilize isolate-scope within the directive..

$scope.control.moveNeedle = function () {
$scope.ScoreRotateNeedle();
 }
return {
            scope: **{control: '='}**,
            restrict: 'E',
            templateUrl: 'svgmeter.html',
            link: link,
            controller: 'delightMeterController'

        };

Insert this snippet of code into your controller

$scope.ctrl = {};

Within your HTML, include

<div ng-app="delightMeterApp" ng-controller="delightMeterController">
    <delight-meter ng-model="delightScore" control = "ctrl"></delight-meter>
    <input id="Text1" type="text" ng-model="delightScore" ng-change="ctrl.rotateNeedle()" />
</div>

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

Tips for creating interactive labels in angular-chart

I'm attempting to attach a click handler to the labels of a chart generated by angular-chart. Is there a method to include a custom event listener or utilize the built-in chart-click directive? Currently, the chart-click directive only returns the M ...

Display radio options when clicked upon

I am in the process of creating a set of radio buttons that will be utilized for capturing values to generate a subscription/modal checkout. My current situation involves having the radio button options visible. However, I aim to achieve a functionality wh ...

What is the best way to limit input to only numbers and special characters?

Here is the code snippet I am working with: <input style="text-align: right;font-size: 12px;" class='input' (keyup.enter)="sumTotal($event)" type="text" [ngModel]="field.value" (focusin)="focusin()" (focusout)="format()" (keyup.ente ...

Place a call directly from the webpage

Is there a way to initiate a phone call using JavaScript? I've tried the code below: document.location.href = "tel:15555551212" While this code takes me to the dial screen of the mobile application, I actually want to place the call directly. Any ...

Navigating discreetly with invisible scroll bar

I am attempting to design a webpage where the scroll bar is hidden, but users can still scroll or click on links to navigate down the page. I have managed to hide the scroll bar, but I am facing an issue where the page jumps to 100% when scrolling. How can ...

An error was encountered when attempting to use the 'await' syntax in a useEffect() function that called axios.get()

To avoid using .then(..), I have switched to utilizing await. I am making a call to a function that includes an Axios request and returns the data as response.data after awaiting for it. My functional component has a useEffect that is meant to initialize a ...

When it comes to adjusting the height of an element, there are two ways to go about it: using $(element).height

function adjustHeight(){ var headerHeight=$(element).find('.header').outerHeight(); console.log(headerHeight); var temp=$(window).height()-headerHeight; console.log(temp); $('.users ...

utilizing class manipulation to trigger keyframe animations in react

Currently, I am delving into my very first React project. In my project, I have implemented an onClick event for one of the elements, which happens to be a button. The aim is to smoothly transition an image's opacity to 0 to indicate that the user ha ...

Determine user connectivity in Angular 4 using Firebase

My current setup involves using Firebase for authentication with Google. However, I am encountering an issue where upon refreshing the page after being connected, I am unable to retrieve the Session/CurrentUser information. firebase.auth().onAuthStateChan ...

Is there a method to adjust the styling of my <header> once the page hits a specific #anchor point?

Seeking some assistance with a website design challenge I am facing. I am currently working on a one-page portfolio site with four #anchor points that serve as "pages". Each div has a height of 100% to fill the entire browser height. The header, which co ...

Using the Ionic framework to transfer data from a controller variable to a page

Hey there! I'm currently working on a hybrid app using the Ionic Framework, but I believe my error lies more within Angular. Here's the code snippet that's giving me trouble: <ion-view class="back" ng-controller="webCtrl" view-title="{{ ...

Troubleshooting iFrame Loading Issues with HTML5 PostMessage

Our code is utilizing the newest postMessage feature in HTML 5 to address cross-domain communication challenges. The issue I am facing is figuring out how to determine if the messages posted to an iFrame have been successfully loaded. If the frame fails to ...

When using RS256 with JWT, the private key will not be accepted

I've been attempting to generate a JWT using 'jsonwebtoken' with RS256. The keys were generated using the following command: ssh-keygen -t rsa -b 4096 -m PEM -f <filename> The private key output appears as follows: -----BEGIN RSA PRIV ...

Creating a dynamic background image for the ul/li div element

As a newcomer to website development, I am currently exploring how to dynamically set images in the ul/li elements within a div. Below is a snippet of the HTML code I have been working on: <div class="results"> <ul class="row"> < ...

Utilize the names of tags to retrieve text content when parsing XML with jQuery's $.parseXML function

Incorporating jquery's $.parseXML() function to extract xml data can be done as follows: For instance, suppose I want to target the book tag which includes nested tags like author and price: //utilizing Sample XML from http://msdn.microsoft.com/e ...

Unlocking the value of the "input" field within an EventListener function in Angular directly from the DOM

In my "characters" module, there is a form with a text field and a button. When the button is clicked, it triggers a function but I am struggling to retrieve the current input text and pass it to the async function. HTML: https://i.sstatic.net/DMF8w.png ...

How to set DIVS to be hidden when the page first loads

I am currently working on a project where I need to use JavaScript to hide certain <div> elements when the page loads. I have also included jQuery in my code. Below is what I have tried so far: $(document).ready(function() { hide(); function hid ...

Increasing numerical section of text with JavaScript

Is there a way to increment the numeric part at the end of a string in JavaScript when certain actions occur? For example: var myString = 'AA11111' increaseStringValue(myString) # Updated value of myString => 'AA11112' Additional ...

Encountering an error with my electron application built using create-react-app

While I'm working on my project, my electron window is showing this error message. TypeError: fs.existsSync is not a function getElectronPath ../node_modules/electron/index.js:7 4 | var pathFile = path.join(__dirname, 'path.txt') 5 | ...

The width of the table remains consistent

I have created a division that includes two tables stacked on top of each other. However, I am facing an issue where the width of the second table remains fixed and does not change even when I try to increase it. Here is the code snippet below: functio ...