2

我的 AngularJS 指令存在绑定时间问题。它的控制器如下所示:

controller: function($element, $scope)
{
    $element.find("input").bind("blur", function()
    {
        SendUpdate();
    });

    $scope.Subtract = function()
    {
         Add(-$scope.step);
    }

    $scope.Add = function()
    {
        Add($scope.step);
    }

    function Add(amount)
    {
        $scope.model = parseInt($scope.model) + parseInt(amount);
        console.log("Model: " + $scope.model);
        SendUpdate();
    }

    function SendUpdate()
    {
        $scope.$emit("ProcessUpdate");
    }
}

到目前为止一切正常,从值 100 开始并添加 10,它会按预期打印出 Model: 110。但是,当事件由提供模型绑定到的变量的父范围处理时,到事件触发时它还没有收到更新的值:

$scope.$on("ProcessUpdate", function()
{
    console.log("MyValue: " + $scope.MyValue);
});

打印出 MyValue: 100,即使它是绑定到指令模型变量的 $scope.MyValue(我也在使用“=”绑定字符)。

实际上,该值正在更新。如果我按下一个打印出相同内容的按钮:

console.log("MyValue: " + $scope.MyValue);

它打印 MyValue 的正确值:110。所以这显然是一个时间问题。看起来事情是按以下顺序发生的:

  1. 更新指令的 $scope.model。
  2. 触发事件。
  3. 处理事件。
  4. 更新父级的 $scope.model。

我需要的是 4 在 1 之后立即发生,因为当事件被触发时,我需要父范围是最新的。

我应该这样做有不同的方式吗?我不想通过事件传递更新的值,因为任何数量的这些指令都可能被触发,并且它们都需要处理父范围。我不想弄清楚发生了什么变化并相应地注入它。我只想在父范围收到指令的新值后触发事件。

谢谢你。

4

2 回答 2

6

试试下面的代码

$scope.$on("ProcessUpdate", function() {
    $timeout(function() {
        console.log("MyValue: " + $scope.MyValue);
    });
});

即使超时为零,它也不会执行,直到插值和 DOM 渲染完成。此处更详细地解释了该行为:

http://ejohn.org/blog/how-javascript-timers-work/

希望对你有用:)

于 2013-06-06T21:36:43.000 回答
2

问题是您正在使用事件(立即)并且双向绑定使用 Angular$digest循环。怎么样而不是使用$on$emit而是使用一个$watch函数呢?

在你的指令中,你会这样做:

$scope.$watch("MyValue", function(newValue, oldValue) {
  console.log("MyValue: " + $scope.MyValue);
});

在您的控制器中,您所要做的就是删除SendUpdate.

于 2013-06-06T19:20:23.360 回答