更新Angular工厂变量时更新控制器变量

Atu*_*ary 4 angularjs

嗨,我有一个问题.我的工厂里有一个对象如下

User: {
   EmailAddress: ""
}
Run Code Online (Sandbox Code Playgroud)

每当我进行http调用时,我想更新User.EmailAddress whith返回的值.在工厂内做这件事的最佳方法是什么?所以在控制器级别我可以将$ scope.Email绑定到工厂变量.这就是我现在正在做的事情

GetLogOnModel: function () {
    if ($location.path().indexOf("login") == 1) {
        var promise = $http.get(config.headers.url + "LogOn").then(function (response) {
            // The return value gets picked up by the then in the controller.
            User.EmailAddress=response.data.Email;
            return response.data
        });
        return promise;
        // Return the promise to the controller
    }
}
Run Code Online (Sandbox Code Playgroud)

在控制器中

AccountFactory.GetLogOnModel().then(function (data) {
  $scope.logOnModel = data;
}, function (err) {
  console.log(err.reason);
  alert(err.reason);
});
Run Code Online (Sandbox Code Playgroud)

gka*_*pak 14

原始类型(如字符串)不受引用约束.因此,您无法EmailAddress直接绑定范围属性并期望它自动更新.
另一方面,对象通过引用绑定,因此您可以执行以下操作:

app.factory('AccountFactory', function (...) {
  ...
  var User = {
    ...
    EmailAddress: null
  };

  function getLogOnModel() {
    $http.get(...).then(function (response) {
      User.EmailAddress = response.data.Email;
    });
  }

  // Init model (or leave it for the controller to init it)
  getLogOnModel();

  return {
    ...
    User: User,
    getLogOnModel: getLogOnModel
  };
});

app.controller('someCtrl', function (..., AccountFactory) {
  $scope.user = AccountFactory.User;
  // Now you can reference `$scope.user.EmailAddress`
  // and it will be kept in sync with `AccountFactory.User.EmailAddress`
});
Run Code Online (Sandbox Code Playgroud)


cod*_*mer 7

它应该很直接.您可以将服务实例或只是电子邮件属性绑定到$scope.

在这里,我只是在5秒后更新电子邮件.

myApp.factory('myService', function($http, $timeout) {
    return {
        email: 'foo@bar.com',
        updateEmail: function() {
            var self = this;
            $timeout(function() {                
                $http.get('/echo/json/').success(function() {
                    self.email = 'bar@foo.com';
                });
            }, 5000);
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

第一种方法: 将范围内的整个服务绑定为:

function MyCtrl($scope, myService) {
    $scope.myService = myService;
    myService.updateEmail();
});

<div ng-controller="MyCtrl">
  myService: {{myService.email}}! 
</div>
Run Code Online (Sandbox Code Playgroud)

第二种方法 只需$watch为电子邮件更新创建自定义:

function MyCtrl($scope, myService) {
    $scope.email = myService.email;
    myService.updateEmail();

    $scope.$watch(function() { return myService.email; }, function(newVal, oldVal) {
       $scope.email = newVal;
    });
}

<div ng-controller="MyCtrl">
  $scope: {{email}}
</div>
Run Code Online (Sandbox Code Playgroud)

我建议第一种方法,因为它只需要一个$watch更新DOM,即{{myService.email}}第二种方法需要两个,$watches即一个更新$ scoped模型($scope.$watch),另一个更新DOM {{email}}.

演示:http://jsfiddle.net/HB7LU/3015/