2015-06-25 2 views
0

Я действительно изо всех сил пытаюсь написать сложную функцию в угловом, что зависит от обещаний. Это мой первый раз, когда я пишу обещание, и я все еще не уверен, что полностью понимаю, как делать то, что я хочу делать с моим кодом.Угловое вложенное обещание

У меня есть переменная var query = searchQuery.getQuery() в контроллере ProfileNavCtrl. Затем в моей службе searchQuerygetQuery извлекает значение localStorage.getItem('searchQuery') и проверяет, является ли это пустой строкой или нулевым значением. Если он не пустой или пустой, он просто возвращает значение контроллеру. Значение должно быть массивом таких пули, как ['foo','foo-bar','foo-bar-baz'].

Если он пуст или пуст, он выполняет вызов $http.get, чтобы получить объект JSON и проанализировать его. Здесь меня ломают вещи. Мне нужно getQuery(), чтобы вернуть значение от $http.get (если начальное значение query равно null), так что этому переменному назначается переменная query контроллера. Как и сейчас, query (в контроллере) всегда имеет значение null или undefined.

Звонок $http.get также вызывает setQuery(), так что запрос сохраняется, и избегаются вызовы в будущем.

Вот мой контроллер:

app.controller('ProfileNavCtrl', ['$scope', '$http', '$location', '$q', 'searchQuery', 
function($scope, $http, $location, $q, searchQuery){ 
    var query = searchQuery.getQuery; 
// do something with query 

А вот моя служба:

app.service('searchQuery', ['$http', '$timeout', '$q', function($http, $timeout, $q){ 
    var query = []; 

    this.getQuery = new Promise(function(){ 
     var query = localStorage.getItem('searchQuery'); 

     if(query == "" || query == [""] || query == null){ 
      var slugArray = []; 
      var query = $http.get('/companies.json') 
      .then(function(resp) { 
       if(resp && resp.data) { 
        for(var i in resp.data) { 
         var result = resp.data[i]; 
         if(resp.data[i].name){ 
          slugArray.push(resp.data[i].name.toLowerCase().split(' ').join('-')); 
         } 
        } 
        setQuery(slugArray); 
       } else { 
        resetQuery(); 
       } 
      }, function(err) { 
       resetQuery(); 
      }).then(function(resp){ 
       return resp; 
      }) 
      return query; 
     } else { 
      return query; 
     }; 
    }).then(function(success){ 
     return success; 
    }); 

UPDATE: вторая попытка Вот мой код контроллера: вар GetQuery = searchQuery.getQuery ();

getQuery.then(function(query){ 
    query = searchQuery.getQuery(); 
    // Check if user is on main site or portal 
    if(location.pathname.split('/')[3] == null){ 
     var currentProfile = location.pathname.split('/')[1]; 
    } else { 
     var currentProfile = location.pathname.split('/')[3]; 
    }; 

    // Get the next/prev query element (if any) 
    console.log('6: '); 
    console.log(query); 
    var prev = query.slice(query.indexOf(currentProfile)-1)[0]; 
    var next = query.slice(query.indexOf(currentProfile)+1)[0]; 

    // Check if next/prev is undefined and if so, set to first/last element in query array 
    if(prev){ 
     var prevProfile = prev; 
    } else { 
     var prevProfile = query.pop(); 
    }; 

    if(next){ 
     var nextProfile = next; 
    } else { 
     var nextProfile = query[0]; 
    }; 

    $scope.goToPrev = function() { 
     // Check if user is on main site or portal 
     if(location.pathname.split('/')[3] == null){ 
      var profileUrl = location.origin + '/' + prevProfile; 
      // window.location = profileUrl; 
      console.log(profileUrl); 
     } else { 
      var profileUrl = location.origin + '/' + location.pathname.split('/').slice(1,3).join('/') + '/' + prevProfile; 
      // window.location = profileUrl; 
      console.log(profileUrl); 
     } 
    }; 

    $scope.goToNext = function() { 
     // Check if user is on main site or portal 
     if(location.pathname.split('/')[3] == null){ 
      var profileUrl = location.origin + '/' + nextProfile; 
      // window.location = profileUrl; 
      console.log(profileUrl); 
     } else { 
      var profileUrl = location.origin + '/' + location.pathname.split('/').slice(1,3).join('/') + '/' + nextProfile; 
      // window.location = profileUrl; 
      console.log(profileUrl); 
     } 
    }; 
}); 

Вот мой обновленный сервис: this.getQuery = функция() { вернуть новый Promise (функция() { вар запрос = localStorage.getItem ('SearchQuery');

 if(query == "" || query == [""] || query == null){ 
      var slugArray = []; 
      return $http.get('/companies.json') 
      .then(function(resp) { 
       if(resp && resp.data) { 
        for(var i in resp.data) { 
         var result = resp.data[i]; 
         if(resp.data[i].name){ 
          slugArray.push(resp.data[i].name.toLowerCase().split(' ').join('-')); 
         } 
        } 
        setQuery(slugArray); 
       } else { 
        resetQuery(); 
       } 
       return slugArray; 
      }, function(err) { 
       resetQuery(); 
      }); 
     } else { 
      return query; 
     }; 
    }); 
}; 
+1

'getQuery' должна быть функция * * это * возвращает * обещание, если вы хотите его называть. – Bergi

+0

Я немного изменил свой код, поэтому 'getQuery' возвращает обещание, но теперь я борюсь с тем, как справиться с обещанием в контроллере. Я хочу получить результат обещания, когда он будет успешным, а затем определим некоторые методы в '$ scope'. – ACIDSTEALTH

ответ

1

в угловых обещаниях предоставляется через $q службы. См более подробно.

основной контур для реализации $ Q обещания в службе она обведена бел ой, я оставлю подробности о том, как сохранить на локальном и т.д. хранения для вас:

this.getQuery = function(){ 
    var deferred = $q.defer(); 
    var query = localStorage.getItem('searchQuery'); 

    if(query == "" || query == [""] || query == null){ 
     $http.get('yoururl').then(function(resp) { 
      // assuming resp is an array, else do your parsing to get array 
      query = resp; 
      deferred.resolve(query); 
     }, function(err) { 
      query = null; 
      deferred.reject(err); 
     }); 
    } else { 
     deferred.resolve(query); 
    }; 
    return deferred.promise; 
}; 

Вы можете использовать это в вашем контроллере, как:

var query = null; 
searchQuery.getQuery().then(function(result) { 
    query = result; 
}, function(err) { 
    // Error occured 
}); 
+0

Я пробовал аналогичную установку, прежде чем это не сработало для меня. Я с тех пор отказываюсь от использования 'offferred', поскольку я читал несколько сообщений в блоге, таких как [этот] (http://pouchdb.com/2015/05/18/we-have-a-problem-with -promises.html), которые говорят, что это плохая практика. Я отправил свою вторую попытку в мой вопрос. У меня есть обещание, которое теперь доставлено контроллеру, я просто не уверен, что с ним делать. – ACIDSTEALTH

+0

'$ q' - это реализация обещаний и плотно интегрированных решений Angular во всех Угловых встроенных сервисах.'q $' может использоваться либо отложенным способом, либо чем-то, что в некоторой степени напоминает обещания ES6. Но мода «отложенная» на сегодняшний день является наиболее часто используемым способом в Angular и 3rd Party Angular modules. ** В любом случае, вам остается использовать '$ q', а не ES6 обещает прямо **, как вы в настоящее время пытаетесь сделать. '$ q' также интегрирован с механизмом наблюдения за моделью видимости в угловом режиме. – Beyers

+0

Итак, вы говорите, что мне нужно использовать '$ q' и что метод ES6, который я пытался реализовать, не будет работать? Теперь я нахожусь в точке, где у меня есть объект обещания 'Promise {[[PromiseStatus]]:« resolved »}', который доставляется моему контроллеру, но я не уверен, как его обрабатывать. – ACIDSTEALTH

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