AngularJS 指令不更新回调范围

标签 angularjs angularjs-directive angularjs-scope

我正在使用指令在 AngularJS 1.5 中创建组件库。因此,我的指令需要具有隔离范围。

我的一些指令有回调,所以你可以传入一个函数来被指令调用。但是,当该指令调用该回调时,$scope 属性的更改似乎并没有像我期望的那样完全更新。

这是一个显示此行为的 Plunker: http://embed.plnkr.co/Rg15FHtHgCDExxOYNwNa/

代码如下:

<script>
    var app = angular.module('myApp', []);
    app.controller('Controller', ['$scope',function($scope) {
        // initialize the value to something obvious
        $scope.clickersValue = "BEFORE";

        // when this call back is called we would expect the value to be updated by updated by the directive
        $scope.clickersCallback = function() {
        //$scope.$apply(); // $apply is not allowed here
        $scope.clickersValueRightAfterCall = $scope.clickersValue;
        console.log("clickersCallback: scope.clickersValue", $scope.clickersValue);
    };
  }
]);

app.directive('clicker', [function() {
  return {
    restrict: 'EA',
    template: '<div ng-click="clicked()">click me!</div>',
    controller: ['$scope', function($scope) {
      $scope.clicked = function() {
        console.log("you clicked me.");
        $scope.newValue = 'VALID';
        $scope.myUpdate();
      }
    }],
    scope: {
      "newValue": "=",
      "myUpdate": "&"
    }
  };
}]);
</script>

因此,当调用 clickersCallback 时,clickersValue 属性仍然具有旧值。我试过使用 $scope.$apply 但是当另一个更新发生时当然是不允许的。我也尝试使用 controller_bind 但得到了相同的效果。

最佳答案

clickersCallback 函数中的代码包装在 $timeout 函数中。

$timeout(function() {
    $scope.clickersValueRightAfterCall = $scope.clickersValue;
    console.log("clickersCallback: scope.clickersValue", $scope.clickersValue); 
});

Updated plunker

The $timeout does not generate error like „$digest already in progress“ because $timeout tells Angular that after the current cycle, there is a timeout waiting and this way it ensures that there will not any collisions between digest cycles and thus output of $timeout will execute on a new $digest cycle. source

编辑 1:正如 OP 在下面所说,指令的用户不必在他的回调函数中编写任何“特殊”代码。

为了实现此行为,我将 $timeout 从 de controller 更改为指令。

Controller 回调函数(未更改):

$scope.clickersCallback = function() {
    $scope.clickersValueRightAfterCall = $scope.clickersValue;
    console.log("clickersCallback: scope.clickersValue", $scope.clickersValue);
};

指令代码(在指令中注入(inject) $timeout):

 $scope.clicked = function() {
     console.log("you clicked me.");
     $scope.newValue = 'VALID';
     $timeout(function() {
         $scope.myUpdate();
     });
 }

Updated plunker

关于AngularJS 指令不更新回调范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40423764/

相关文章:

angularjs ng-options从嵌套的json数组中选择

javascript - 从 Angular Directive(指令)调用 Controller 函数

Angularjs 单元测试 watch 回调即使在范围内也不会被调用。$digest

javascript - $routeParams.param 返回未定义

angularjs - 如何将光标焦点设置在输入字段上?

javascript - 手动显示 AngularStrap 下拉列表 - 如何?

jquery - 如何检测 Angular 中是否*未*单击指令元素

javascript - 为什么这个 Angular 模型没有被完全覆盖?

javascript - 使用 "as controller"语法时,如何在子 Controller 中引用父级的范围?

javascript - 根据当前日期排序数组