$ apply两个操作,一个取决于另一个

时间:2013-11-21 13:55:07

标签: angularjs angularjs-directive

在我的角度指令中,在回调中,我将$apply称为:

  1. 设置$scope.model.something
  2. 使用$scope.onAction()
  3. 调用model.something

    我在一次$apply调用中执行此操作,但在调用onAction()时,model.something仍未定义。

    同时,在$ apply之后,{{model.something}}具有正确的值,因此model.something会正确更新。

    我希望设置model.something,因此我可以在onAction()中使用它。如何修复以下代码?

    这是指令(我跳过了不相关的代码):

    .directive(function () {
      return {
        scope: {
          ngModel: '=',
          onAction: '='
        },
        compile: function (element, attrs) {
          return function (scope) {
            // This is some callback which is invoked
            // outside of digest cycle.
            function callback() {
              // Here I want to set model and call onAction callback
              scope.$apply(function () {
                scope.ngModel = 'something';
                scope.onAction();
              });
            }
          }
        }
      };
    })
    

    同时,我的控制器看起来像:

    var MyController = function ($scope) {
      $scope.model = {};
    
      $scope.onAction = function () {
        // Here I want $scope.model.something to be set to "something"
        // But it's undefined.
        alert($scope.model.something);
      };
    }
    

    最后,HTML:

    <div ng-controller="MyController">
      {{ model.something }}
      <my-directive ng-model="model.something" on-action="onAction"/>
    </div>
    

    还有一件事,我知道我可以致电scope.onAction('something'),我正在寻找其他解决方案。

    这是the fiddle

2 个答案:

答案 0 :(得分:1)

你可以简单地将每一行包装到它自己的$ apply回调中:

compile: function (element, attrs, transclude) {
  return function (scope, element, attrs) {
    setTimeout(function () {
      var something = 'lorem ipsum';
      scope.$apply(function () {
        scope.ngModel = something;
      });
      scope.$apply(function () {
        scope.onAction();
      });
    }, 200);
  };
}

Fiddle

答案 1 :(得分:1)

使用$timeout

$timeout(function(){
    scope.onAction(something);
});

或使用$watch

scope.$watch("ngModel",function(){
    scope.onAction(something);
});