2016-12-14 2 views
0

Я переношу свой код Angular 1.x, чтобы использовать более новый, более предпочтительный синтаксис, чтобы избежать использования $ scope и использования контроллера в качестве синтаксиса. Однако у меня проблема с получением данных от службы.AngularJS Ctrl как синтаксис с сервисами

Вот мой пример:

var myApp = angular.module('myApp', []); 
 

 
myApp.controller('MainCtrl', ['$http', '$location', 'userService', 
 
    function($http, $location, userService) { 
 

 
    this.name = 'John Doe'; 
 

 
    // this.userData = { 
 

 
    // } 
 

 
    this.userData = userService.async().then(function(d) { 
 
     return d; 
 
    }); 
 

 

 
    console.log(this.userData); 
 

 

 
    } 
 
]); 
 

 
myApp.service('userService', function($http) { 
 

 
    var userService = { 
 
    async: function() { 
 
     // $http returns a promise, which has a then function, which also returns a promise 
 
     var promise = $http.get('https://jsonplaceholder.typicode.com/users').then(function(response) { 
 
     // The then function here is an opportunity to modify the response 
 
     // console.log(response); 
 
     // The return value gets picked up by the then in the controller. 
 
     return response.data; 
 
     }); 
 
     // Return the promise to the controller 
 
     return promise; 
 
    } 
 
    }; 
 
    return userService; 
 

 
});
<body ng-app="myApp"> 
 
    <div id="ctrl-as-exmpl" ng-controller="MainCtrl as mainctrl"> 
 

 
    <h1>Phone Numbers for {{mainctrl.name}}</h1> 
 

 
    <button ng-click="">newest</button> 
 
    <p>{{mainctrl.userData}}</p> 
 
    <ul> 
 
     <li ng-repeat="users in mainctrl.userData">{{users.phone}} -- {{users.email}}</li> 
 
    </ul> 
 
    </div> 
 
</body>

Эта проблема у меня в том, что данные, возвращаемые из userService.async является объектом, который я не могу показаться, чтобы развернуть через для получения данных, поскольку данные являются дочерними элементами состояния $$, которые, как представляется, не используются в представлении.

Если это не правильный способ использования служб в синтаксисе контроллера As/$ без ограничений, каков правильный способ?

Живой пример здесь: http://plnkr.co/edit/ejHReaAIvVzlSExL5Elw?p=preview

ответ

1

Вы пропущенный важной частью обещаний, - когда года u верните значение из обещания, вы вернете новое обещание, которое решит это значение.

Текущий способ установить данные, возвращаемые обещании локальной переменной в контроллере заключается в следующем:

myApp.controller('MainCtrl', ['$http', '$location', 'userService', 
    function($http, $location, userService) { 

    this.name = 'John Doe'; 

    userService.async().then(function(d) { 
     this.userData = d; 
    }); 
    } 
]); 

Но теперь вы в улове из-за рамки this, так что общий использовать переменную «placeholder» для контроллера this scope.

myApp.controller('MainCtrl', ['$http', '$location', 'userService', 
    function($http, $location, userService) { 

    var $ctrl = this; // Use $ctrl instead of this when you want to address the controller instance 

    $ctrl.name = 'John Doe'; 

    userService.async().then(function(d) { 
     $ctrl.userData = d; 
    }); 
    } 
]); 
+0

Если я выхожу из «как» и «placeholder» (в моем plnkr: http://plnkr.co/edit/KBnz7yQkyBp3B8MPFpYd?p= Предварительный просмотр Я использую 'vm'), они оба имеют возвращенные данные из вызова userService $ http. Тем не менее, только использование заполнитель работает для получения данных для отображения в представлении. Почему это? – TWLATL

+1

Из-за области JS, когда вы находитесь внутри анонимной функции в 'then', ключевое слово' this' адресует анонимную функцию, поэтому вам нужно установить 'this' экземпляра функции контроллера переменной, поэтому этот экземпляр будет доступен во всех «вспомогательных» функциях внутри контроллера. –

0
this.userData = userService.async().then(function(d) { 
    return d; 
}); 

В этом кусочке кода this.userData фактически определяется как обещание. Если вы хотите, чтобы данные, которые возвращаются, вы должны использовать параметр d от вашего .thenfunction так:

userService.async().then(function(d){ 
    this.userData = d; 
    //a console.log() here would determine if you are getting the data you want. 
}); 

Редактировать Я просто заметил в вашей службе, что вы уже используете .data на ваш ответ объект.

Честно говоря, мой лучший совет вам было бы просто вернуть обещание от http.get() вызова внутри вашей службы, как это:

myApp.service('userService', function($http) { 
    var userService = { 
     async: function() { 
      return $http.get('https://jsonplaceholder.typicode.com/users'); 
     } 
    }; 
    return userService; 

}); 

И тогда вы могли бы использовать что-то вроде этого, чтобы захватить и использовать ответ данные:

userService.async().then(function(response){ 
    this.userData = response.data; 
); 

Это может быть немного чище раствором

+0

Хорошо, вот как у меня был код, структурированный изначально, но с его настройкой таким образом, this.userData возвращается как неопределенный, когда он регистрируется. Пример здесь: http://plnkr.co/edit/ejHReaAIvVzlSExL5Elw?p=preview – TWLATL

+0

Я только что обновил свой ответ с другой структурой, которая может помочь вам – CraigR8806

+0

Я просто посмотрел на ваш плункер. 'this.userData' никогда не будет определен там, где вы' console.log() 'it out. Это связано с тем, что когда этот 'console.log' запускается, он все еще ждет ответа от веб-сервера. 'this.userData' определяется, если вы добавляете в' console.log (this.userData) 'внутри своего'.затем '' function' после того, как он установлен на d – CraigR8806

Смежные вопросы