为什么将 ng-select 替换为自定义指令会导致$http请求不会每隔一段时间发送一次

Why has replacing ng-select with a custom directive caused $http requests not to be sent every other time

本文关键字:一段时间 一次 http 替换 ng-select 自定义 指令 为什么 请求      更新时间:2023-09-26

edit 我现在通过在指令的模板中使用ng-click修复了错误,但我仍然有兴趣知道ng-click的作用与element.bind不同以及为什么它很重要

我确实有一个 ng 选择框来更新我的模型

<td><select ng-model="tune.dummyStandard" ng-options="opt.value as opt.label for opt in dropdowns.playback" ng-change="update()" > <option value="">-- rate performance --</option> </select></td>

在漫长的验证过程结束时,它创建了一个新的$http请求(通过$resource.$update)并保存了记录。

我现在已更改为使用自定义指令

<td j-performance-rater data-tune="tune"></td>

附加了以下侦听器(实际的侦听器有点复杂,但我已经非常严格地检查了它是否总是按预期触发tune.resource.$update

element.bind('click', function (ev) {
   // code for validation and setting of model props
   tune.resource.$update();
});

现在,奇数单击会创建$http对象但不发送,偶数单击会发送以前创建的$http对象并创建并成功发送一个新对象。即使单击在指令的不同实例上,也会始终发生这种情况。我尝试在范围上玩弄$digest$apply,但它们没有任何影响(我不确定它们是否应该像$http在我看来它应该独立于摘要周期)。

谁能想到问题可能是什么?

完整的指令代码

directives.directive('jPerformanceRater', function () {
    return {
    // transclude: true,
        scope: true,
        templateUrl: '/views/directives/performance-rater.html',
        compile: function(element, attrs) {
            return function (scope, element, attrs) {
                var tune = scope[attrs.tune || 'tune'];
                scope.tune = tune.tune;
                element.bind('click', function (ev) {
                    ev.cancelBubble = true;
                    var btn = ev.target.className.indexOf('icon') > -1 ? ev.target.parentNode : ev.target;
                    if (btn.className.indexOf('btn')  === -1) {
                        return;
                    }
                    tune.dummyStandard = +btn.textContent;
                    tune.update(); // most of the validation happens in here and then it calls resource.$update()
                });
                element.addClass('performance-rater');
            };
        }
    };
});

和模板

<span class="btn btn-small" ng-repeat="rating in dropdowns.playback" type="checkbox"
   title="{{rating.label}}">{{rating.value}}<i class="icon icon-star{{rating.value == 0 ? '-empty' : ''}}"></i></span>

更改 :

element.bind('click', function (ev) {
  tune.resource.$update();
});

自:

element.bind('click', function (ev) {
  scope.$apply(function(){
     tune.resource.$update();
  });
});

应该做这个伎俩。bind('click')ng-click之间的区别在于ng-click触发角$digest循环,而bind('click')不会。任何$http$resource请求仅在角度$digest周期(内部角度事件循环周期)内调用时才触发对服务器的请求。因此,在您的情况下,您调用了resource.update但在角度$digest周期之外,因此不会向服务器发出请求,而只是"计划"直到下次触发角度事件循环(例如执行ng-change时)并启动对服务器的请求。