【问题标题】:AngularJS Two way data binding between controller and serviceAngularJS控制器和服务之间的双向数据绑定
【发布时间】:2015-02-23 18:29:34
【问题描述】:

我有一个 Angular JS 服务,定义如下:

'use strict';

angular.module('Offering.AccountService', [])

.service('Account', function($http, config) {

    var account = this;

    account.accountDetails = {};

    this.getAccountDetails = function(){
        var request = $http({
            method: 'GET',
            url: config.accountURL,
            headers: {
                'X-Parse-Application-Id': config.applicationID,
                'X-Parse-REST-API-Key': config.restAPIKey,
            }
        })
        .success(function(data, status, headers, config) {
            console.log('Successfully aqquired account details');
            account.accountDetails = data.results[0];

        })
        .error(function(data, status, headers, config) {
            console.warn(status);
        });
    }


});

这个服务调用一个端点来检索一些数据,我在主模块的run函数中调用这个方法,如下所示:

'use strict';

angular.module('Offering', [
    'routerRoutes'
])

.run(function(Account){
    Account.getAccountDetails();
})

在我的控制器中,我有一个名为 balance 的变量,我想在其中存储从服务检索到的值,如下面的代码所示:

'use strict';

angular.module('Offering.HomeController', [])

.controller('HomeCtrl', function(Account) {

    this.data = {
        message: "Account Details",
        updateBalance: function() {
            Account.getAccountDetails()
        },
        balance: Account.accountDetails.balance
    }

    // this.$watch(
    //     function () { return Account.accountDetails; },
    //     function (data) {
    //         $scope.data.balance = data.balance
    //     },
    //     true
    // );
})

在设置控制器数据对象后返回来自服务的数据,因此余额字段不会被填充。如果我使用被注释掉的 $scope.watch 方法,那么数据对象会被正确填充。但是,我假设不需要这样做,因为服务和控制器之间存在双向数据绑定。任何帮助是极大的赞赏。谢谢!

【问题讨论】:

  • 这通常通过从您的服务返回一个承诺并在承诺解决时在您的控制器中设置数据来处理。

标签: angularjs angular-services


【解决方案1】:

.run 函数不会停止等待getAccountDetails 返回值。因此,当您分配 this.data.balance = Account.accountDetails.balance 时,您实际上是在这样做:this.data.balance = undefined

根据上面的评论,典型的方法是让getAccountDetails() 返回一个承诺,如下所示:

this.getAccountDetails = function(){
   return $http({...})
       .then(function(response){
          console.log("successfully returned balanace", response.data);
          return response.data;
       });
}

然后,在控制器中:

var vm = this;
Account.getAccountDetails()
  .then(function(accountDetails){
     vm.balance = accountDetails.balance;
  });

【讨论】:

  • 感谢您的回复。我不想在控制器中执行此操作,因为我想使用多个控制器中返回的数据。在设置任何控制器之前,我有什么办法可以做到这一点,这样我就不必在每个控制器中都这样做?
  • 如果您填充而不是覆盖最初为空的accountDetails 对象,那么您可以$watch 对其进行更改。但是,这并不有效,因为它将在每个摘要上完成。另一种方法是使用$routeProviderresolve 属性或更强大的$stateProvider - 这允许您在导航到视图之前解决所有异步依赖项,并将它们注入所有依赖控制器。
  • 谢谢,这似乎是我要找的。​​span>
【解决方案2】:

你不能在返回promise的函数上设置watch,最好你可以在this.data上设置watch,在控制器中使用这个关键字时,它们的watch方式不同。

代码

$scope.$watch(angular.bind(this, function () {
    return this.data; 
  }), function (newVal, oldVal) {
    // now we will pickup changes to newVal and oldVal
  });

希望对你有帮助,谢谢。

【讨论】:

    猜你喜欢
    • 2018-10-06
    • 1970-01-01
    • 2013-12-23
    • 2018-01-03
    • 1970-01-01
    • 2015-07-23
    • 2013-07-30
    • 2013-05-10
    • 2016-05-28
    相关资源
    最近更新 更多