Angular:保持工厂数据更新的最佳方法?

时间:2015-02-06 04:30:28

标签: javascript angularjs

好的,我有一个UserFactory,其返回值有一个user属性,如下所示:

angular.module('app')
  .factory('UserFactory', function () {

    return {
      user: user
    };


    function user () {
      return {
        age: 'test',
        loggedIn: false
      }
    };

我在我的应用程序的几个地方注入了这个,我希望能够在任何地方更改loggedIn属性,至少在它注入的每个控制器中都是如此。

我有两个问题:

  1. 如何从注入它的控制器更改loggedIn属性?即:

    angular.module('app')
      .controller('HeaderCtrl', function ($scope, $element, $attrs, UserFactory) {
    
    $scope.loggedIn = UserFactory.user().loggedIn;
    
    $scope.change = function () {
      //This doesn't work
      UserFactory.user().loggedIn = !UserFactory.user().loggedIn;
    };
    
      $scope.anotherChange = function () {
      //This doesn't work
      $scope.loggedIn = !$scope.loggedIn;
    };
    
    });
    
  2. 和2.

    如何更新user信息并将其链接到我的数据库。换句话说,如果有人从另一台计算机登录并更改age属性(将在我的数据库中更新),我该如何将其与另一台计算机同步?

    由于

3 个答案:

答案 0 :(得分:1)

对于第一个问题,您需要正确检查和理解您的代码。

在工厂函数中,传递一个未存储在任何位置的对象(最终)。每次调用服务时,它都会传递一个新对象。因此,首先创建一个对象,然后传递它。这样,后续调用将始终返回相同的对象。

app.factory('UserFactory', function() {
    var userObject = {
        age: 25
        loggedIn: false
    };

    return {
        get: function () {
            return userObject;
        },
        set: function (user) {
            userObject = user;
        }            
    };
});

如上所示,当您致电工厂的get()功能时,您将获得用户详细信息。当您调用set()函数并传递最新详细信息时,您可以覆盖用户对象。

对于第二个问题,执行它的最佳方法是调用一个使用上述服务的函数。每次路线更改时调用此函数。也就是说,如果用户移动到新的页面/路由,请调用将从后端获取最新详细信息的函数,然后调用上述服务的set()函数来存储最新的用户详细信息。

答案 1 :(得分:0)

回答你的问题

<强> 1 您应该将工厂设置为这样的......

angular.module('app')
.factory('UserFactory', function () {

  var user = {};

  user.loggedIn = false;

  user.login = function() {
    // Logic to login your user
    user.loggedIn = true;
  }

  // Now return the whole user object
  return user;
  // Remember anything after a return is not executed

});

现在,在您的控制器中,您可以通过

访问loggedin变量
UserFactory.loggedIn // will be true or false

<强> 2 这个有点难度,你可以采用几种不同的方式。

可能最简单的方法是使用套接字。由于您尝试更新数据库中单个更改所连接的所有客户端中的某些内容,因此您需要一些方法来强制从服务器到客户端的交互,而无需客户端请求它。

这就是套接字的作用。您可以将其设置为“侦听”来自服务器的事件,并在触发这些事件时作出反应。

或者,您可以每隔一定时间轮询服务器,或者在路由更改时检查新数据。

答案 2 :(得分:0)

保持工厂更新的最佳方式是不使用$ scope。 这是使用共享服务但不使用$ scope的控制器之间共享数据的更高级解决方案。

<强> HTML

<div ng-app="myApp">
    <div ng-controller="Controller1 as ctrl">
        </br> 
        <table>
            <tr>
                <td><B> Enter Age in Controller1</B></td>
                <td><input type="text" ng-model="ctrl.userAge"></select></td>
                <td><button ng-click="ctrl.userLoggedIn=true"/>Submit</td>
            </tr>
        </table>
    </div>
    <div ng-controller="Controller2 as ctrl">
        <table>
            <tr>
                <td><B> Age in controller2 : </B></td>
                <td>{{ctrl.userAge}}</td>
            </tr>
            <tr>                
                <td><B> LoggedIn in controller2 : </B></td>
                <td>{{ctrl.userLoggedIn}}</td>
            </tr>
        </table>
    </div>
</div>

<强> JS

(function(app) {

    function SharedService() {
        this.user = {};
    }
      angular.extend(SharedService.prototype, {
        getUser: function() {
            return this.user;
        },
        setUser: function(user) {
            this.user = user;
        }
    });

    function Controller1(SharedService) {
        this.sharedService = SharedService;
    }

      Object.defineProperty(Controller1.prototype,
            'userAge', {
                enumerable: true, //indicate that it supports enumerations
                configurable: false, //disable delete operation
                get: function() {
                    return this.sharedService.getUser().age;
                },
                set: function(val) {
                    this.sharedService.getUser().age=val;
                }
            });

    Object.defineProperty(Controller1.prototype,
            'userLoggedIn', {
                enumerable: true, //indicate that it supports enumerations
                configurable: false, //disable delete operation
                get: function() {
                    return this.sharedService.getUser().loggedIn;
                },
                set: function(val) {
                    this.sharedService.getUser().loggedIn=val;
                }
            });


    function Controller2(SharedService) {
        this.sharedService = SharedService;
    }

    Object.defineProperty(Controller2.prototype,
            'userAge', {
                enumerable: true, //indicate that it supports enumerations
                configurable: false, //disable delete operation
                get: function() {
                    return this.sharedService.getUser().age;
                },
                set: function(val) {
                    this.sharedService.getUser().age=val;
                }
            });

    Object.defineProperty(Controller2.prototype,
            'userLoggedIn', {
                enumerable: true, //indicate that it supports enumerations
                configurable: false, //disable delete operation
                get: function() {
                    return this.sharedService.getUser().loggedIn;
                },
                set: function(val) {
                    this.sharedService.getUser().loggedIn=val;
                }
            });


    app.service('SharedService', SharedService);
    app.controller('Controller1', Controller1);
    app.controller('Controller2', Controller2);

})(angular.module('myApp', []));