AngularJs 中的两种方式数据绑定不使用异步回调

Posted

技术标签:

【中文标题】AngularJs 中的两种方式数据绑定不使用异步回调【英文标题】:Two way databinding in AngularJs not working with async callback 【发布时间】:2014-04-17 03:01:32 【问题描述】:

所以我正在尝试构建一个 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 不知何故为空。

非常感谢您对此提供的任何帮助。真的,真的很感激。

【问题讨论】:

需要注意的一点是,通过更改其中一个输入字段导致表单变为无效然后有效会使用所有数据更新指令的 $scope.model(但它仍然没有正确的干净模型)。 【参考方案1】:

如果您在控制器被实例化之前在resolve 中获取数据,那么指令应该从中读取它就好了:

app.config(function($routeProvider) $routeProvider.route('myRoute', 网址:'/我的路线', 解决: 获取数据:函数($http) return $http.get('获取数据').then(function(data) 返回数据; ); ); 功能页面控制器($范围,getData) // 在你的控制器被实例化之前,你的 $http 调用中的 getData 现在是可用的 // 并且可以被你的指令使用 $scope.controllerModel = 获取数据;

我不确定为什么控制台日志给出的信息相互矛盾

【讨论】:

以上是关于AngularJs 中的两种方式数据绑定不使用异步回调的主要内容,如果未能解决你的问题,请参考以下文章

解决使用angularjs时页面因为{{ }}闪烁问题的两种方式ngBind,ngCloak

Java开启异步的两种方式

组件和同一元素上的指令之间的两种方式数据绑定?

没有 ngmodel 指令的两种方式数据绑定

angularJs模版注入的两种方式

AngularJS 1.5 - 如何在组件上设置两种方式绑定