2014-11-26 2 views
2

Я пытаюсь получить новые запросы Firebase, работающие на моем заводе, но я застрял. Я хочу вернуть значение «логотипа» из таблицы моих оппонентов на основе имени оппонента. Я могу получить пример с console.log из Firebase Docs работает:Как использовать запрос Firebase в угловой фабрике?

function OpponentService($firebase) { 
    var factory = {}; 
    var _url = 'https://somefirebaseproject.firebaseio.com/opponents'; 
    var _ref = new Firebase(_url); 

    factory.getLogo = function(opponent) { 
     _ref.orderByChild('name').equalTo(opponent).on("child_added", function(snapshot){ 
      console.log(snapshot.val().logo); 
     }); 
    }; 

    return factory; 
} 

Когда я называю мою фабрику с OpponentService.getLogo(opponentName) в мой контроллер, я получаю правильный логотип идентификатор в моей консоли. Но как я могу вернуть значение вместо отправки его на консоль? Я хочу сохранить его в переменной вроде этого: $scope.opponentLogo = OpponentService.getLogo(opponentName). Я попробовал несколько вариантов с ответным заявлением, как это:

factory.getLogo = function(opponent) { 
     _ref.orderByChild('name').equalTo(opponent).on("child_added", function(snapshot){ 
      return snapshot.val().logo; 
     }); 
}; 

Но, видимо, я не в полной мере понять, как заводы работают в Угловое, потому что я получаю undefined. Может быть, ценность пока недоступна, и я должен каким-то образом использовать обещание? Любой, кто может указать мне в правильном направлении?

ответ

5

Вы возвращаете значение логотипа из анонимной функции внутри вызова Firebase on(), но вы ничего не возвращаете от getLogo().

Возвращение обещания было бы хорошим способом сделать это. Это, как вы извлекаете противник логотип с AngularFire, если нет гарантии opponentName не будет уникальной:

// getLogo() returns a promise that you can bind to the UI. 
// When loading finishes, the binding will get the opponent's logo value. 
factory.getLogo = function (opponentName) { 
    var opponentsArray = $firebase(_ref.orderByChild('name').equalTo(opponentName)).$asArray(); 

    // $loaded() returns a promise, so we can use the then() method to add 
    // functionality when the array finishes loading and the promise resolves. 
    var r = opponentsArray.$loaded().then(function() { 
     // Now return the logo for the first matching opponent 
     return opponentsArray[0].logo; 
    }); 

    return r; 
}; 

Если opponentNameявляется уникальными, я бы пересмотреть структуру данных, чтобы вы могли использовать opponentName в качестве ключ для противников. Тогда вы гарантированно получите одного противника и может принести его:

var opponent = $firebase(_ref.child(opponentName)).$asObject(); 

Если вы не используете AngularFire, вы можете вернуть обещание с помощью $q службы угловых в. Следующие должны работать:

factory.getLogo = function(opponent) { 
    $q(function (resolve, reject) { 
     function successCallback(snapshot) { 
      resolve(snapshot.val().logo); 
     }; 

     function cancelCallback(error) { 
      reject(error); // pass along the error object 
     }; 

     _ref.orderByChild('name').equalTo(opponent) 
      .on("child_added", successCallback, cancelCallback); 
    }); 
}; 

Вы можете присвоить результат getLogo() в области видимости переменных и привязки будет обновлять в пользовательском интерфейсе, когда Firebase возвращает значение.

+0

Спасибо за ваш ответ, я проверю сегодня, если это сработает. Я уже использую AngularFire, так что это должно быть легко сказать? – Lennert

+0

Вы пытаетесь вернуть логотип для одного противника? Вам нужен доступ или привязка к другим свойствам противника в вашем приложении? –

+0

Да в этом методе мне нужно только вернуть логотип для одного противника. Но весь завод содержит больше методов, например 'factory.getAllOpponents'. – Lennert

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