AngularJS指令不';t更新回调的作用域

AngularJS指令不';t更新回调的作用域,angularjs,angularjs-directive,angularjs-scope,Angularjs,Angularjs Directive,Angularjs Scope,我正在使用指令在AngularJS 1.5中创建一个组件库。因此,我的指令需要有隔离作用域 我的一些指令具有回调,因此您可以传入一个函数以被指令调用。然而,当该指令调用该回调时,对$scope属性的更改似乎并不像我期望的那样完全更新 下面是一个Plunker,显示了这种行为: 下面是代码的样子: <script> var app = angular.module('myApp', []); app.controller('Controller', ['$scope'

我正在使用指令在AngularJS 1.5中创建一个组件库。因此,我的指令需要有隔离作用域

我的一些指令具有回调,因此您可以传入一个函数以被指令调用。然而,当该指令调用该回调时,对$scope属性的更改似乎并不像我期望的那样完全更新

下面是一个Plunker,显示了这种行为:

下面是代码的样子:

<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>

var-app=angular.module('myApp',[]);
app.controller('controller',['$scope',function($scope){
//将值初始化为明显的值
$scope.clickersValue=“BEFORE”;
//调用此回调时,我们希望通过指令更新值
$scope.clickersCallback=函数(){
//$scope.$apply();//$apply在此不允许
$scope.clickersValueRightAfterCall=$scope.clickersValue;
log(“clickersCallback:scope.clickersValue”,$scope.clickersValue);
};
}
]);
应用程序指令('clicker',[function(){
返回{
限制:“EA”,
模板:“单击我!”,
控制器:['$scope',函数($scope){
$scope.clicked=function(){
log(“你点击了我”);
$scope.newValue='VALID';
$scope.myUpdate();
}
}],
范围:{
“newValue”:“=”,
“myUpdate”:“&”
}
};
}]);

因此,当调用ClickerCallback时,ClickerValue属性仍然具有旧值。我尝试过使用$scope.$apply,但当另一个更新发生时,当然不允许使用它。我还尝试使用controller_bind,但效果相同。

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

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

$timeout不会产生类似“已在进行$DIEST”的错误,因为$timeout告诉Angular,在当前周期之后,有一个超时等待,这样可以确保摘要周期之间不会发生任何冲突,因此$timeout的输出将在新的$DIEST周期上执行。

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

$timeout(function() {
    $scope.clickersValueRightAfterCall = $scope.clickersValue;
    console.log("clickersCallback: scope.clickersValue", $scope.clickersValue); 
});
为了实现这种行为,我将$timeout从de-controller更改为指令

控制器回调函数(无更改):

$scope.clickersCallback = function() {
    $scope.clickersValueRightAfterCall = $scope.clickersValue;
    console.log("clickersCallback: scope.clickersValue", $scope.clickersValue);
};
 $scope.clicked = function() {
     console.log("you clicked me.");
     $scope.newValue = 'VALID';
     $timeout(function() {
         $scope.myUpdate();
     });
 }
指令代码(在指令中注入$timeout):

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

Gabriel,谢谢你的创造性方法。但是,这要求指令用户在代码中做一些特殊的事情。我真的在寻找一种方法,让指令用户可以像我们在ng click中那样使用表达式。但是,我仍然支持你的建议。也许你可以包装
$scope.myUpdate()
在指令中的
$timeout
内调用。这是你想要的吗?是的!这正是我想要的!我在你的建议后尝试了这一点,但我一定是在代码中不知怎的弄错了。你能将其作为答案发布,以便我可以将其标记为已回答吗?非常感谢,这太好了。