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

时间:2022-03-12 19:47:18

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:

我有一个开源项目,我正在升级到使用角度1.2rc3。本质上它处理表单按钮上的承诺。在这个plnkr http://plnkr.co/edit/vQd97YEpYO20YHSuHnN0?p=preview中,您应该能够单击右侧的“保存”并看到控制台中出现“单击”,因为它应该在指示:

            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:

使用1.2,尽管执行了以下代码,但此方法不再执行:

            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?

我无法弄清楚为什么这个功能不会被执行....任何想法?

2 个解决方案

#1


3  

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.

Angular 1.2中的一些指令优先级已经改变(参见“重大改变”)。这是一个更新的plunkr,它只是在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.

这会导致您的指令(替换ngClick属性的值)在ngClick指令使用属性值使用$ parse创建函数指针之前执行。

#2


3  

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:

你真的不应该修改链接功能的ng-click属性。我认为这对你有用,并且修改优先级是一个黑客。我认为有一种更简单的方法来做你想要做的事情。看一下修改过的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.

我将您的指令修改为忙碌点击并完全替换ng-click。使用和操作ng-click是没有意义的(开始时这是一个非常简单的指令)。如果您有任何疑问,请告诉我。

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);
            }
        }
    };
});

#1


3  

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.

Angular 1.2中的一些指令优先级已经改变(参见“重大改变”)。这是一个更新的plunkr,它只是在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.

这会导致您的指令(替换ngClick属性的值)在ngClick指令使用属性值使用$ parse创建函数指针之前执行。

#2


3  

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:

你真的不应该修改链接功能的ng-click属性。我认为这对你有用,并且修改优先级是一个黑客。我认为有一种更简单的方法来做你想要做的事情。看一下修改过的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.

我将您的指令修改为忙碌点击并完全替换ng-click。使用和操作ng-click是没有意义的(开始时这是一个非常简单的指令)。如果您有任何疑问,请告诉我。

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);
            }
        }
    };
});