2

このコードはほとんど機能していますが、コントローラー内の User オブジェクトから変更が反映されるのを確認するのが困難です。

私がやろうとしているUserのは、サイト上の現在のユーザーのすべての側面を管理する単一のサービスを構築することです。例: User.login()User.logout()User.currentUserUser.isLoggedInなど。

私はまだAngularとngResourceに比較的慣れていないことを覚えておいてください:-)。

  • これを設計するためのより良い/よりAngularの方法はありますか?
  • $resource ファクトリのカスタム プロパティは可能ですか?
  • ここに が必要なように感じ$rootScope.$apply()ますか?

    /**
     * The $resource factory.
     */
    angular.module('myApp.services', ['ngResource'])
      .factory('User', ['$resource', '$http', function($resource, $http) {
        var User,
            anonymousUser,
            currentUser,
            isLoggedIn;
    
        anonymousUser = { uid: 0, pass: null, name: 'Anonymous' };
        currentUser = angular.copy(anonymousUser);
        isLoggedIn = false;
    
        User = $resource('api/user/:verb', {}, {
    
          login: {
            method: 'POST',
            params:  { verb: 'login' },
            isArray: false,
            // (Ab)using the transformResponse callback to update currentUser
            // and isLoggedIn when necessary.
            transformResponse: $http.defaults.transformResponse.concat([
              function (data, headersGetter) {
                if (angular.isObject(data) && angular.isObject(data.user)) {
                  currentUser = data.user;
                  isLoggedIn = true;
                }
                // TODO: Flipping to anonymous user when a login error occurs. Double check if this logic is sound.
                else {
                  currentUser = angular.copy(anonymousUser);
                  isLoggedIn = false;
                }
    
                return data;
              }
            ])
          },
    
          logout: {
            method: 'POST',
            params:  { verb: 'logout' },
            isArray: false, // eg: [true] transformed to { result: true }
            // (Ab)using the transformResponse callback to update currentUser
            // and isLoggedIn when necessary.
            transformResponse: $http.defaults.transformResponse.concat([
              function (data, headersGetter) {
                if (angular.isArray(data) && data.length > 0) {
                  if (data[0] === true) {
                    currentUser = angular.copy(anonymousUser);
                    isLoggedIn = false;
                  }
    
                  return { result: data[0] };
                } else {
                  // TODO: Deal with indeterminate state here. Is the user logged in still or not?
                  // TODO: Return error.
                  return { result: false };
                }
              }
            ])
          }
        });
    
        // FIXME: Adding extra properties onto our $resource here. These ARE visible in the controller but bindings and $watch don't work on them.
        User.isLoggedIn = isLoggedIn;
        User.currentUser = currentUser;
    
        // FIXME: Attempting to bring these objects under the purview of Angular but this isn't helping.
        $rootScope.isLoggedIn = isLoggedIn;
        $rootScope.currentUser = currentUser;
    
        return User;
      }]);
    
    
    /**
     * The controller.
     */
    angular.module('myApp.page', [])
      .controller('NavbarCtrl', ['$scope', 'User', function ($scope, User) {
        // These work, but are not dynamically updated when User.login() and User.logout() are called.
        $scope.currentUser = User.currentUser;
        $scope.isLoggedIn = User.isLoggedIn;
    
        // FIXME: $watch is only called once, changes in User.login() and User.logout() do not invoke $watch here.
        $scope.$watch('currentUser', function (newVal, oldVal) {
          console.log([newVal, oldVal], 'Watching curentUser');
        }, true);
      }])
    
4

3 に答える 3

1

角度のある方法ではありません。create service - create service が必要な場合は、angular にこのためのインストゥルメントがあります。これについての情報はこちらで読むことができます。工場にはロジックがあってはなりません。そのため、サービス メソッドのログイン、ログアウトなどを作成し、$http を使用してサーバーにリクエストを送信します。

于 2013-07-05T13:43:01.647 に答える
0

たぶん、これにプロトタイプを使用することができます。しかし、これが本当に角度のある方法なのかはまだわかりません

.factory('User', ['$resource', ($resource) ->
  user = $resource API_PATH + "/user", {},
    update: {method: 'PUT'}
  user.prototype.login = ->
    blah_blah()

  user.prototype.logout = ->
    blah_blah()

  user

そして、次のように使用します。

user = new User() user.login();

于 2013-07-05T13:51:33.330 に答える