Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

attrs.$set('ngClick', functionName + '()'); no longer working in angular 1.2rc3

I have an open source project that I'm working on upgrading to work with angular 1.2rc3. Essentially it handles promises on form buttons. In this plnkr http://plnkr.co/edit/vQd97YEpYO20YHSuHnN0?p=preview you should be able to click "Save" on the right side and see a "clicked" appear in the console, because it should execute this code in the directive:

            scope[functionName] = function () {
                console.log('clicked');
                //if it's already busy, don't accept a new click
                if (scope.busy === true) {
                    return;
                }

                scope.busy = true;
                var ret = scope.$eval(onClick);
                if (angular.isDefined(ret) && ret.hasOwnProperty('then')) {
                    ret.then(function () {
                        scope.busy = false;
                    });
                }
            };

With 1.2, this method no longer gets executed despite the following code being executed:

            if (angular.isDefined(attrs.ngClick)) {
                console.log('test');
                attrs.$set('ngClick', functionName + '()');
            }

I haven't been able to figure out why this function won't get executed.... any ideas?

like image 637
Webnet Avatar asked Oct 24 '13 17:10

Webnet


2 Answers

Some of the directive priorities have changed (see "Breaking Changes") in Angular 1.2. Here's an updated plunkr which simply sets a negative priority on your busy button directive in angular-form-ui.js.

restrict: 'A',
priority: -100, // <-- This is the only change I made
controller: ...

This causes your directive, which replaces the value of the ngClick attribute, to execute before the ngClick directive uses the value of the attribute to create a function pointer using $parse.

like image 120
jandersen Avatar answered Oct 18 '22 12:10

jandersen


You really should not be modifying the ng-click attribute from your link function. I think it's a fluke that it ever worked for you, and modifying the priority is a hack. I think there is an easier way to do what you are trying to do though. Take a look at the modified plunkr:

http://plnkr.co/edit/EypQbCc5wpw5xBWSiVuA?p=preview

I modified your directive to be busy-click and replaces ng-click altogether. There's no point in using and manipulating ng-click (it is an extremely simple directive to begin with). Let me know if you have any questions.

BTW, if you did need to add or modify directives, you would do this through a compile function, never through the link function.

    directive('busyClick', function () {
    return {
        restrict: 'A',
        scope:{
          busyClick: '&',
          busyText: '@'
        },
        link: function (scope, el, attrs) {

            el.on('click', function(){
                scope.$apply(function(){

                  console.log('clicked');
                  //if it's already busy, don't accept a new click
                  if (scope.busy === true) {
                    return;
                  }
                  setBusy();
                  var ret = scope.busyClick();
                  if (angular.isDefined(ret) && ret.hasOwnProperty('then')) {
                    ret.then(function () {
                        setNotBusy();
                    });
                  }

                });

            });

            var originalText = el.text();

            function setBusy(){
              scope.busy = true;
              el.addClass('busy')
              if(angular.isDefined(scope.busyText)){
                el.text(scope.busyText);
              }
            }

            function setNotBusy(){
              scope.busy = false;
              el.removeClass('busy')
              el.text(originalText);
            }
        }
    };
});
like image 3
Daniel Tabuenca Avatar answered Oct 18 '22 12:10

Daniel Tabuenca