2014-07-25 3 views
0

해결 방법이있는 경로를 처음 방문 할 때 개체 요청이 전송되지 않습니다. 페이지를 방문하는 유일한 방법은 url 바에서 경로가 올바른지 (입력 또는 링크 클릭) 캐시하지 않고 페이지를 새로 고치는 것입니다 (Firefox의 경우 Ctrl + Shift + r 또는 Chrome의 경우 Ctrl + F5).처음 AngularJS가 작동하지 않음

처음 방문하면 링크가 작동합니다.

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.'); 
     } 
    ); 
    }; 
    } 
]); 
+0

콘솔 오류가 있습니까? – V31

+0

콘솔 오류가 없으며 요청이 없습니다. – Siecje

+0

그냥 서버 측에서 인증을해야한다는 것을 기억하십시오 ... – mb21

답변

0

이에 내 첫번째 생각은 해결 된 객체는 하드 부하에 해결되는 것입니다. 앱이 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; 
     }); 
    }, 
    } 

이 일에, 나는 또한 당신이보기에 바인딩하기 전에 자바 스크립트 객체로 개체를 반환하는 것이 좋습니다 것입니다. 컨트롤러에 '번들'을 주입하여 컨트롤러에서이 작업을 수행 할 수 있습니다.

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; 
     }; 
     } 
    }). 

그런 다음 매개 변수가 전달 된 컨트롤러에서 액세스 할 수 있습니다. 원본 주소 :이 도움이 http://www.undefinednull.com/2014/02/17/resolve-in-angularjs-routes-explained-as-story/

희망,

패트릭

+0

지연이 정의되지 않았습니다. .error() 내부에서 생각합니다. 또한 오류가 발생하기 전에 성공을 마감했습니다. https://dpaste.de/aQRJ – Siecje

+0

반환 값을 감싸는 함수에 '$ q'를 인스턴스화 했습니까? 주사를 맞았는지 확인하십시오. – Maximus

+0

위의 내용은 JSHint에서 사용하지 않는 것으로 보여줍니다. 나는 반환이 가야하는 곳에 100 %가 아니며 보통 안으로 들어갑니다. 나는 '$ q'의존성을 가지고있다. – Siecje

0

이보십시오. 나는 그것을 테스트하지 않았으므로 완벽하지는 않을 수도 있지만 아마도 올바른 방향으로 향하는 데 도움이 될 것입니다.

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; 
     }); 
     }); 
    }, 
    }; 
}]); 

은 요청 완료시 해결되는 약속을 반환합니다. .then() 함수에서 값을 반환하면 해당 값이 체인의 다음 .then()으로 이동합니다. UI-Router의 해결책은 주어진 약속을 자동으로 푸는 것입니다. 주어진 것이 있으면 그냥 반환합니다. 약속은 자동으로 각도 1.2+에서 언랩되지 않으므로 캐시에서 작업 할 때 직접 언 래핑해야합니다.

+0

로그인 후 리디렉션이 깨지는 것을 제외하면 작동하는 것처럼 보입니다. 내 게시물에 그 코드를 추가했습니다. – Siecje

0

귀하의 질문은 2 부분입니다.

1) 왜 내 첫 번째 해결로 주정부의 해결을 해결할 수 없습니까?

처음으로 "데이터를 이행하겠다는 약속을 이행하겠다는 약속"을 반환합니다. 그것은 사슬로 묶인 약속과 같습니다. 데이터를 확보하겠다는 약속을 되 돌렸을 때이를 해결하기 위해 $ digest cycle이 추가로 필요합니다. $ http.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. 

또한

Angular JS: Chaining promises and the digest cycle

2) 문제를 해결하기 위해 무엇을 변경할 수 있습니다 이것 좀 봐?

두 가지 작업을 수행 할 수 있습니다. $ http.get()은 그 자체로 약속이기 때문에 반환하십시오. promise 객체를 캐시하는 이유는 무엇입니까? 실제 데이터를 캐시해야합니다. 또한 $ resource 및 $ http를 사용하면 {cache : true}를 전달할 수 있으며 결과가 캐시됩니다. 또는 제어하려는 경우 $ cacheFactory를 사용할 수 있습니다. 이 경우 캐시에 실제 결과를 배치 할 수 있으며 promise 오브젝트는 배치 할 수 없습니다.

+0

$ http.get() 요청에 {cache : true}를 추가하면 데이터베이스에 새 항목을 추가하고 캐시 된 결과를 더 이상 사용하지 않으려는 경우 어떻게 캐시를 삭제할 수 있습니까? – Siecje

+0

var defaultCache = $ cacheFactory ('$ http'); 그러나 자신의 캐시를 사용해야합니다. 내 요점은 재발용하기보다는 $ cachefactory를 사용하는 것이었다. 더 많은 제어 권한을 가질 수 있도록 기본 캐시를 직접 캐시로 바꿀 수 있습니다. $ http에 대한 Angular 문서. $ http.defaults.cache 속성을 업데이트하여 기본 캐시를 $ cacheFactory로 작성된 새 객체로 변경할 수 있습니다. cache 속성을 true로 설정 한 모든 요청은 이제이 캐시 객체를 사용합니다. config/application에서 한번 실행하십시오. – bhantol

관련 문제