2016-10-05 2 views
0

컨트롤러가 getMyList 서비스 함수를 호출하지만 $ http 호출이 완료되는 데 시간이 걸리므로 myLists가 채워지지 않은 문제가 있습니다.

어떻게이 문제를 해결할 수 있습니까?

서비스

app.factory('myService', function($http) { 
    var myList = []; 

    $http.get("http://myService/json.data").then(function (resp) { 
     myLists = resp.data; 
    }); 

    return { 
     getMyList: function (name) { 
      for (var i = 0; i < myLists.length; i++) { 
       if (myList[i].name == name) { 
        return myLists[i]; 
       } 
      } 
     } 
    } 
} 

컨트롤러 :

여기 내 코드입니다

app.controller('MainCtrl', function(myService,$scope) { 
    var testName = "test" 
    myService.getMyList(testName).then(function(resp) { 
     // do something with resp data 
    }); 
}); 
+0

일? 그들 중 누구? – Hitmands

+0

라우터가 없습니다. 하지만 컨트롤러에서 캐시 된 myLists에서 목록을 반환하는 myService.getMyList를 호출해야합니다. – SimpleCoder

답변

2

당신 오타를 수정하고 더 나은 이름을 선택하는 첫번째 필요. 그럼 당신은 오히려 요소보다 요소의 약속을 반환해야 (즉, 컨트롤러가 그렇고, 무엇을 기대입니다) : 단지 HTTP 호출을 반환하여 서비스 있도록

app.factory('myService', function($http) { 
    // this defines a promise which, when resolved, contains an array of elements 
    var listPromise = $http.get("http://myService/json.data").then(function(resp) { 
     return resp.data; 
    }); 

    return { 
     // this returns a promise which, when resolved, contains the element with the given name 
     getElementFromList: function(name) { 
      return listPromise.then(function(list) { 
       return list.filter(function(element) { 
        return element.name === name; 
       })[0]; 
      }); 
     } 
    }; 
}); 
+0

ok.이것은 나의 원래 질문에 대한 가장 가까운 대답이다. myService.getElementFromList (testName) .then (function (resp)) {// do something} – SimpleCoder

+0

을 호출하면 컨트롤러 클래스에서 resp가 아직 정의되지 않은 상태입니다. 그러면 해당 이름의 목록에 요소가 없을 것입니다. 디버깅을하면 어떻게됩니까? –

0

모든 HTTP 호출이 각도에서 promise을 반환 promise을 반환합니다.

그런 다음 컨트롤러에서 당신은 service 또는 api 호출의 응답을 처리하기 위해 다시 thenerror 전화를 사용할 수 있습니다.

공장 :

app.factory('myService', function($http) { 
    var myList = []; 
    return { 
     getMyList: function (name) { 
      $http.get("http://myService/json.data") 
     } 
    } 
} 

컨트롤러 :

app.controller('MainCtrl', function(myService,$scope) { 
    var testName = "test" 
    myService.getMyList() 
    .then(function successCallback(resp) // Success call back 
    { 
      if(resp.data) 
      { 
      myLists = resp.data; 
      for (var i = 0; i < myLists.length; i++) { 
       if (myList[i].name == testName) { // you can use your testName here itself. 
        return myLists[i]; 
       } 
      } 

      } 
    }, 
    function errorCallback(resp) // Error call back 
    { 
     console.log(resp) 
    }); 
}); 
0

일부 클라이언트 측 라우터 구현을 사용하는 경우는 : 모두 Ui.RouterngRoute 구현 Route.Resolve를 보라.

라우터가 없다면 할 수있는 작은 트릭이 있습니다. 공장에서 객체 참조를 반환하기 만하면 해상도가 발생할 때 해당 객체를 예상 값으로 채우십시오 :

angular 
 
    .module('test', []) 
 
    .constant('API', 'https://jsonplaceholder.typicode.com') 
 
    .factory("PostResolved", function($http, API) { 
 
    var result = []; 
 
    $http 
 
     .get(API + '/posts/1') 
 
     .then(function(response) { 
 
     result.push(response.data); 
 
     }) 
 
    ; 
 
    
 
    return result; 
 
    }) 
 

 
    .controller('TestCtrl', function($scope, PostResolved) { 
 
    $scope.posts = PostResolved; 
 
    }) 
 
;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<section ng-app="test"> 
 
<article ng-controller="TestCtrl"> 
 
    <div ng-repeat="post in posts"> 
 
    <h1 ng-bind="post.title"></h1> 
 
    </div> 
 
</article> 
 
</section>

0

이유는 다음과 같은 것을 사용하지 마십시오

app.factory('myService', function($http) { 
 
    return { 
 
     getMyList: function (name) { 
 
      var myList = []; 
 
      $http.get("http://myService/json.data").then(function (resp) { 
 
       myLists = resp.data; 
 
      }); 
 
      
 
      scope.$evalAsync(function() { 
 
       for (var i = 0; i < myLists.length; i++) { 
 
        if (myList[i].name == name) { 
 
         return myLists[i]; 
 
        } 
 
       } 
 
      }); 
 
     } 
 
    } 
 
}

+0

요점은 getMyList 메소드 외부에서 $ http.get을 호출하려고합니다. 어떻게 든 HTTP 호출의 결과를 캐시해야합니다. $ evalAsync에 대한 확신이 없으면 범위에 결과를 저장하지 않습니다. – SimpleCoder

+0

myLists = resp.data를 래핑하기 위해 $ evalAsync를 사용하려고합니다. 그럼, 잘하면 도울 수 – Kerisnarendra

0

필자는 $ timeout을 사용하여이 문제를 해결할 수있었습니다. 더 나은 제안을 가진 사람은 누구에게나 알려줍니다. 나는 범위를 가져올 수 없습니다. $ evalAsync 당신이 어떤 라우터가 않습니다

서비스

app.factory('myService', function($http, $timeout) { 
    var lists = []; 

    $http.get("http://myService/json.data").then(function (resp) { 
     lists = resp.data; 
    }); 

    return { 
     getMyList: function (name) { 
      return $timeout(function() { 
       for (var i = 0; i < lists.length; i++) { 
        if (lists[i].name == name) { 
         return lists[i]; 
        } 
       } 
     }, 2000) 

    } 
} 

컨트롤러

app.controller('MainCtrl', function(myService,$scope) { 
    var testName = "test" 
    myService.getMyList(testName).then(function(resp) { 
     // do something with resp data 
    }); 
}); 
+0

이것은 잘못된 답변입니다. 당신의 http 응답은 2 초전에 오는데, 그것이 작동하는 이유입니다. 시간이 더 걸리면 어떨까요? – ram1993

+0

예, 알고 있습니다. 제안과 개선에 대해 열려 있습니다. – SimpleCoder

+0

코드와 유사하게 [펜] (https://codepen.io/anon/pen/KgQgKk?editors=1011)을 만들었습니다. 나는 JBNizet이 정답을 가지고 있다고 믿는다. 또 다른 해결책은 $ q입니다. 그러나 그 필요는 없습니다. 두 경우 모두 약속대로 돌아갈 것입니다. – ram1993

관련 문제