AngularJs中的双向数据绑定不能与异步回调一起使用

时间:2014-03-12 18:27:33

标签: angularjs data-binding asynchronous

所以我试图构建一个AngularJS应用程序,并且在与异步回调一起使用时,在控制器和指令之间进行双向数据绑定会遇到一些麻烦。我有一个页面控制器,从服务器提取数据,然后使用多个自定义窗体指令来编辑数据。这是我的设置:

function pageController($scope, $http) {
  // this is what the data will look like
  $scope.controllerModel = {
    obj1: {},
    obj2: {}
  }

  $http.get('get the data').then(function(data) {
    $scope.controllerModel = data; // fill in the data
    $scope.$broadcast('formDataReady'); // tell the forms the data is ready
  });
}

指令:

module('blah').directive('customForm', function() {
  return {
    restrict: 'E',
    scope: { model: '=' },
    transclude: true,
    replace: true,
    controller: function($scope, $attrs) {
      $scope.cleanModel = $scope.model ? _.cloneDeep($scope.model) : {};

      $scope.reset = function() {
        $scope.model = _.cloneDeep($scope.cleanModel);
      };

      $scope.isClean = function() {
        return _.isEqual($scope.model, $scope.cleanModel);
      };

      // Let page controllers tell the from when the model has been loaded
      $scope.$on('formDataReady', function() {
        console.log('custom-form: resetting the clean model');
        $scope.reset();
        console.log($scope);
        console.log($scope.model);
      });

      $scope.reset();
    },
    template:
    '<div>' +
      '<form name="form" novalidate>' +
        '<div ng-transclude></div>' +
        '<div class="form-actions">' +
          '<button class="btn btn-primary" ' +
              'ng-click="save()" ' +
              'ng-disabled="form.$invalid || isClean()">' +
            'Save</button>' +
          '<button class="btn" ' +
              'ng-click="reset()" ' +
              'ng-disabled=isClean()>' +
            'Cancel</button>' +
        '</div>' +
      '</form>' +
    '</div>'
  };
});

还有一点HTML:

<div ng-controller="pageController">
  <custom-form model="controllerModel.obj1">
    <!-- inputs with ng-model to edit the data -->
  </custom-form>
  <custom-form model="controllerModel.obj2">
    <!-- inputs with ng-model to edit the data -->
  </custom-form>
</div>

问题是指令的模型不会因异步回调而更新。 真正奇怪的是,在指令的事件监听器中,这两个console.log调用似乎给出了相互矛盾的信息:

console.log($scope):
  ...
  model: { object with data inside it as expected } 
  ...

console.log($scope.model):
  Object {} // empty

所以在第一个日志中,范围有模型,但$ scope.model在某种程度上是空的。

非常感谢您对此的任何帮助。真的,非常感谢。

1 个答案:

答案 0 :(得分:0)

如果在实例化控制器之前将数据放在resolve中,那么指令应该从中读取它:

app.config(function($routeProvider) {

    $routeProvider.route('myRoute', {
      url: '/myroute',
      resolve: {
         getData: function($http) {
           return $http.get('get the data').then(function(data) {
              return data;      
           }
         }
      }
    });

});

function pageController($scope, getData) {
    // getData from your $http call is now available before your controller was instantiated
    // and can be used by your directive
    $scope.controllerModel = getData;
}

我不确定为什么控制台日志会提供相互矛盾的信息