Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 首先,AngularJS解决方案不起作用_Javascript_Angularjs - Fatal编程技术网

Javascript 首先,AngularJS解决方案不起作用

Javascript 首先,AngularJS解决方案不起作用,javascript,angularjs,Javascript,Angularjs,我第一次访问带有解析的路由时,不会发送对对象的请求。访问页面的唯一方法是确保url栏中的路由正确(键入或单击链接),并在不缓存的情况下刷新页面(Firefox中的ctrl+shift+r或Chrome中的ctrl+F5) 在我访问它之后,第一次链接将起作用 app.config(['$stateProvider', function($stateProvider){ $stateProvider.state('users', { templateUrl: '/app/Users/t

我第一次访问带有解析的路由时,不会发送对对象的请求。访问页面的唯一方法是确保url栏中的路由正确(键入或单击链接),并在不缓存的情况下刷新页面(Firefox中的ctrl+shift+r或Chrome中的ctrl+F5)

在我访问它之后,第一次链接将起作用

app.config(['$stateProvider', function($stateProvider){

  $stateProvider.state('users', {
    templateUrl: '/app/Users/templates/users.html',
    controller: 'Users',
    resolve: {
      'users': function(Objects, $stateParams){
        return Objects.getUsers();
      }
    },
    url: '^/users'
  });

  $stateProvider.state('user', {
    templateUrl: '/app/Users/templates/user.html',
    controller: 'User',
    resolve: {
      'user': function(Objects, $stateParams){
        return Objects.getUser($stateParams.id);
      }
    },
    url: '^/users/:id/'
  });
}]);

app.factory('Objects', ['$http', '$q', function($http, $q){
  /* Retrieve objects once */
  var _cache = {};

  function cache(key, promiseGetterFn) {
    if (key in _cache) {
      return _cache[key];
    }
    else {
      var promise = promiseGetterFn();
      _cache[key] = promise;
      return promise;
    }
  }
  return {
    unsetKey: function(key){
      delete _cache[key];
    },
    getUsers: function() {
      return cache('users', function () {
        var deferred = $q.defer();
        $http.get(HOST + '/api/v1.0/users/all').then(
          function (result) {
            deferred.resolve(result);
          });
        return deferred.promise;
      });
    },
    /*
    getUsers: function(){
      return cache('users', function(){
        return $http.get(HOST + '/api/v1.0/users/all').success(
          function(data, status, headers, config){
            return data.users;
          }
        );
      });
    },
    */
/*
    getUsers: function(){
      return cache('users', function(){
        var deferred = $q.defer();
        return $http.get(HOST + '/api/v1.0/users/all').then(
          function(result){
            deferred.resolve(result.data.users);
          },
          function(status){
            deferred.reject(status);
          }
        );
        return deferred.promise;
      });
    },
*/
    getUser: function(id){
      return cache('user_' + id, function(){
        var deferred = $q.defer();
        return $http.get(HOST + '/api/v1.0/user/' + id).then(
          function(result){
            deferred.resolve(result.data.user);
          },
          function(status){
            deferred.reject(status);
          }
        );
        return deferred.promise;
      });
    },
  };
}]);

app.run(['$rootScope', '$location', 'LocalService', function($rootScope, $location, LocalService){

  $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
    if (!toState.publicAccess && !LocalService.get('loggedIn')){
      /* Store the route they were trying to access */
      LocalService.set('next', $location.path());

      $location.path('/login');
    }
  });
}]);
登录代码后重定向

app.factory('AuthInterceptor', ['$q', '$injector', '$location', 'LocalService', function($q, $injector, $location, LocalService){
  /* Send Authorization in the header of each http request if there is a token */
  return {
    request: function(config){
      if (LocalService.get('token')){
        /* Using btoa to do Base64 */
        /* LocalService.password is only used on login to get token and will be empty ('') when using the token */
        config.headers.Authorization = 'Basic ' + btoa(LocalService.get('token') + ':' + LocalService.get('password'));
      }
      return config;
    },
    responseError: function(response){
      if(response.status === 401 || response.status === 403){
        /* Log the user out */
        LocalService.unset('loggedIn');
        LocalService.unset('token');
        LocalService.unset('user');
        $location.path('/login');
      }
      return $q.reject(response);
    }
  };
}]);

app.config(['$httpProvider', function($httpProvider){
  $httpProvider.interceptors.push('AuthInterceptor');
}]);

app.run(['$rootScope', '$location', 'LocalService', function($rootScope, $location, LocalService){

  $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
    if (!toState.publicAccess && !LocalService.get('loggedIn')){
      /* Store the route they were trying to access */
      LocalService.set('next', $location.path());

      $location.path('/login');
    }
  });
}]);

app.controller('Login', ['$scope', '$http', '$location', 'growl', 'LocalService',
  function($scope, $http, $location, growl, LocalService){
    $scope.email = '';
    $scope.password = '';

    $scope.submitLogin = function submitLogin(){
      LocalService.set('token', $scope.email);
      LocalService.set('password', $scope.password);
      $http.get(HOST + '/api/v1.0/token').
        success(function(data, status, headers, config) {
          LocalService.set('token', data.token);
          LocalService.set('loggedIn', true);
          LocalService.set('password', '');
          /* Set current user */
          $http.get(HOST + '/api/v1.0/authenticate').then(function(result) {
            LocalService.set('user', JSON.stringify(result.data));
            if (LocalService.get('next')){
              var next = LocalService.get('next');
              LocalService.unset('next');
              console.log(next);
              $location.path(next);
            }
            else{
              $location.path('/');
            }
          });
        }
      ).
      error(function(data, status, headers, config) {
          /* invalid credentials growl */
          growl.addErrorMessage('Invalid username or password.');
        }
      );
    };
  }
]);

我对此的第一个想法是,解析对象仅在硬负载下解析。从index.html实例化应用程序后,部分视图可能不会记录对象是否存在。我将尝试使工厂(api)返回的对象成为实际的承诺。现在,我从未见过像你这样的承诺,但我没有看到任何“推迟。解决”或“改变。拒绝”。例如:

 return {
    getBundles: function(){
      return cache('bundles', function(){
        var deffered = $q.defer
        return $http.get(HOST + '/api/v1.0/bundles/all').success(
          function(data, status, headers, config){
            deferred.resolve(data.bundles);
          }.error(function(status){
            deferred.reject(status);
        )};
        return deferred.promise;
      });
    },
  }
在执行此操作时,我还建议您在将对象绑定到视图之前将对象返回到javascript对象。这将在控制器中完成,并将“bundle”注入控制器

var thisBundle = bundles.data.bundles;
thisBundle.then(function(data){
    $scope.bundles = data;
});
我发现的另一个解决方案是在路由中使用解析来包装所有项目。试试这个:

resolve: {
        'allProducts' : function(){
            var theResolvePromise = $q.defer();
            theResolvePromise.resolve({
                bundles: ['Objects', function(Objects){
                  return Objects.getBundles();
                }],
                products: ['Objects', function(Objects){
                  return Objects.getProducts();
                }],
                technologies: ['Objects', function(Objects){
                   return Objects.getTechnologies();
                }],
                deliveryCategories: ['Objects', function(Objects){
                  return Objects.getDeliveryCategories();
                }],
             });
             return theResolvePromise.promise;
         };
      }
    }).
然后,您将在控制器中通过传递的参数访问该文件。 检索自:

希望这有帮助


帕特里克试试这个。我没有测试它,所以它可能不是完美的,但它可能会帮助你指向正确的方向

app.factory('Objects', ['$http', function($http){
  var _cache = {};

  function cache(key, getterFn) {
    if (_cache[key] == null) {
      _cache[key] = getterFn();
      _cache[key].then(function (result) {
          _cache[key] = result;
      });
    }

    return _cache[key];
  }

  return {
    unsetKey: function(key){
      delete _cache[key];
    },
    getUsers: function() {
      return cache('users', function () {
        return $http.get(HOST + '/api/v1.0/users/all');
      });
    },
    getUser: function(id){
      return cache('user_' + id, function() {
        return $http.get(HOST + '/api/v1.0/user/' + id).then(function (result) {
          return result.data.user;
        });
      });
    },
  };
}]);

$http.get
返回在请求完成时解析的承诺。从
.then()
函数返回一个值将把该值弹出到链中的下一个
.then()
中。UI路由器的解决方案会自动取消承诺(如果给定)。如果给了其他任何东西,它只会返回它。承诺不会在Angular 1.2+中自动展开,因此当您在缓存中工作时,您需要自己将其展开。

您的问题分为两部分

1) 为什么我的第一个决心不是为州下决心

第一次返回“承诺兑现承诺兑现数据”时。这就像一个被锁住的承诺。如果您返回获取数据的承诺,则需要额外一个$digest周期来解决此问题$get()返回一个承诺

In AngularJS the results of promise resolution are propagated asynchronously, inside a $digest cycle. So, callbacks registered with then() will only be called upon entering a $digest cycle.
也看看这个

2) 您可以更改什么来解决问题

你可以做两件事 只需返回$http.get(),因为这本身就是一个承诺。 为什么缓存承诺对象?您应该缓存实际数据。
另外,使用$resource和$http,您可以传递{cache:true},结果将被缓存。或者,如果您希望控制,您可能希望使用$cacheFactory。在这种情况下,可以将实际结果放置在缓存中,而不是promise对象中

没有控制台错误,只是没有请求。请记住也要在服务器端进行身份验证…我在服务器端进行身份验证,只要我使用缓存刷新,或者这是第二次或更长时间,就可以工作。这可能与您的问题无关,但如果a)使用承诺链接,您的代码可以更短更简单,因此,不要通过
$q.defer
创建承诺,而是使用成功+错误回调的返回值;b) 您使用库函数来进行缓存,或者使用未定义的I'm get deferred。我认为在.error()中。我也在错误发生之前结束了成功。您是否为包装返回的函数实例化了“$q”?确保您有注入。上面的差异显示为JSHint未使用。我不是百分之百地确定回报应该放在哪里,通常是放在里面。我确实有“$q”依赖项。我用另一个解决方案更新了答案,并在返回时做了更多解释。看看这是否有效。我还在一个网站上附加了一个URL,它很好地解释了我在学习时使用的URL。
$http
调用了返回承诺。这似乎有效,只是它在登录后中断了我的重定向。我已经在我的帖子中添加了这方面的代码。如果我将{cache:true}添加到$http.get()请求中,当我在数据库中添加一个新项并且不再想使用缓存结果时,如何删除缓存?var defaultCache=$cacheFactory('$http');但是,您应该拥有自己的缓存。我的观点是使用$cachefactory,而不是重新发明。您可以用自己的缓存替换默认缓存,这样您就可以拥有更多的控制权。根据Angular文档,价格为$http。通过更新$http.defaults.cache属性,可以将默认缓存更改为新对象(使用$cacheFactory构建)。所有将其缓存属性设置为true的请求现在都将使用此缓存对象。在应用程序级别的config/run中执行此操作一次。