简体   繁体   中英

ng-change event not working

I have created a custom directive using Angular JS. I have a function inside the controller which i'm trying to call on an ng-change event from a text box. but the function is not getting called. Here is my code:

<script>
    var delightMeterApp = angular.module('delightMeterApp', []);
    delightMeterApp.directive('delightMeter', function () {
        return {
            scope: true,
            restrict: 'E',
            template: '<div id="delightmeter"></div>',
            link: function (scope, element) {


                newdiv = jQuery('<div/>', {
                    id: 'delightContainer',
                    class: 'singlenote'
                }).appendTo('#delightmeter');

                var appendstring = "";
                appendstring += "<svg width='500px' height='300px' version='1.1' xmlns='http://www.w3.org/2000/svg>'";
                appendstring += "<g>";
                appendstring += "<text x='100' y='220' fill='black'>0</text>";
                appendstring += "<text x='300' y='220' fill='black'>100</text>";
                appendstring += "<path class='arc' id='arc1' d='' />";
                appendstring += "<path class='arc' id='arc2' d='' />";
                appendstring += "<path class='arc' id='arc3' d='' />";
                appendstring += "<path class='arc' id='arc4' d='' />";
                appendstring += "<path class='arc' id='arc5' d='' />";
                appendstring += "<g class='needleset'>";
                appendstring += "<circle class='needle-center' cx='200' cy='200' r='5'></circle>";
                appendstring += "<path class='needle' d='M 195 198 L 200 100 L 205 202'></path>";
                appendstring += "</g></g></svg>";

                newdiv.append(appendstring);

                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;
                }
            },
            template: '<div id="delightmeter"></div>',
            controller: "delightMeterController"

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

        $scope.fun = function () {
            alert("called");
        }
    });
</script>

Following is my HTML

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

Is it correct to use same controller both for the custom directive and the input control. What am i doing wrong here?

Sooraj,

Like what NexusDuck says you should never manipulate the DOM in your controller. I have reorganized your code to have the DOM manipulation in the Directive and the Controller to just call the Rotate Needle function. The Rotate Needle function does get called in the Directive.

This the HTML

<div ng-controller="delightMeterController">
<delightmeter delight-meter-reference='delightMeterReference'></delightmeter>
<input id="txtScore" type="text" ng-model="delightScore" ng-change="delightMeterReference.RotateNeedle(delightScore)" />{{delightScore}}
</div>

This is your 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 RotateNeedle(delightScore) {
            console.log(delightScore);
            $('.needleset').css({
                "transform": "rotate(" + delightScore + "deg)",
                "transform-origin": "50% 95%"
            });
        }

        if ($scope.delightMeterReference) {
            $scope.delightMeterReference.RotateNeedle = function (delightScore) {
                RotateNeedle(delightScore);
            }
        }
    }
    return {
        restrict: 'E',
        templateUrl: 'components/comp01/comp01.html',
        scope: {
            delightMeterReference: '='
        },
        link: link
    };
})

And this is your Controller

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

    $scope.delightScore = 0;
    $scope.delightMeterReference = {};


})

Thanks, Shivas

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM