问题
Sorry for the length of this but it's driving me a little bit crazy:
Let's say I want to get an item's "title" and ".priority" key values when it loads.
First let's see how every thing's laid out:
$scope.items = $firebase(new Firebase("https://****.firebaseio.com"));
$scope.items.$on('loaded', function() {
console.log($scope.items);
});
With that we get:
> Object {$bind: function, $add: function, $save: function, $set: function, $remove: function…}
> $add: function (item, cb) {
> $bind: function (scope, name) {
> $child: function (key) {
> $getIndex: function () {
> $on: function (type, callback) {
> $remove: function (key) {
> $save: function (key) {
> $set: function (newValue) {
> this is my item: Object
$$hashKey: "012"
$id: "this is my item"
$priority: 2884707
title: "this is the title of my item"
__proto__: Object
> __proto__: Object
Looks good, let's try to grab that $priority:
console.log($scope.items.$child('$priority'));
Oops:
Uncaught Error: Firebase.child failed: First argument was an invalid path: "$priority". Paths must be non-empty strings and can't contain ".", "#", "$", "[", or "]"
Fine, we'll skip that for now and just try for the title:
console.log($scope.items.$child('title'));
> Object {$bind: function, $add: function, $save: function, $set: function, $remove: function…}
> $add: function (item, cb) {
> $bind: function (scope, name) {
> $child: function (key) {
> $getIndex: function () {
> $on: function (type, callback) {
> $remove: function (key) {
> $save: function (key) {
> $set: function (newValue) {
> __proto__: Object
No title.
Okay, let's try it a different way :
var firstItem = $scope.items.$getIndex()[0]; //returns $ids in order of priority
console.log($scope.items.$child(firstItem));
> Object {$bind: function, $add: function, $save: function, $set: function, $remove: function…}
> $add: function (item, cb) {
> $bind: function (scope, name) {
> $child: function (key) {
> $getIndex: function () {
> $on: function (type, callback) {
> $remove: function (key) {
> $save: function (key) {
> $set: function (newValue) {
title: "this is the title of my item"
> __proto__: Object
But now there's no priority!
Kitchen sink swearing at the computer time:
console.log($scope.items.title);
> undefined
console.log($scope.items[0].title);
> Uncaught TypeError: Cannot read property 'title' of undefined
console.log(Object.keys($scope.items));
> ["$bind", "$add", "$save", "$set", "$remove", "$child", "$on", "$getIndex"]
What am I missing? I can manage to get the 'title' by doing a couple U-turns, (figuring out what the item's $id is using '$getIndex()', grabbing the nth item and then making another call using '$child()' ), but even that doesn't work for $priority. Is there an easier way to get key values from within AngularFire v2? Or any way at all to get the $priority?
回答1:
I believe I am / was experiencing the same issue. Hopefully this is related to your experience. Namely:
$scope.items = $firebase(new Firebase("https://xxxxxx.firebaseio.com"));
$scope.items.$on('loaded', function() {
console.log($scope.items['some key']); // this writes undefined to console
});
What I noticed is that this actually does work if I don't rely on the loaded
event. E.g in the HTML:
<a href="#" data-ng-click="logItem()">click me</a>
and in the JS:
$scope.items = $firebase(new Firebase("https://xxxxxx.firebaseio.com"));
$scope.logItem = function() {
console.log($scope.items['some key']); // this works
}
Clicking on the "click me" link logs my item to the console as expected.
Feels like the collection at loaded
time isn't fully populated with the underlying items from firebase.
回答2:
The $child
method should only be used to create a new AngularFire reference. Calling $child
is the same as calling $firebase(new Firebase(parentULR + "/childName"))
. In your example, if all you are trying to do is to get the $priority
and title
for a given object, you can simply do:
$scope.items = $firebase(new Firebase("https://****.firebaseio.com"));
$scope.items.$on('loaded', function() {
var item = $scope.items['your-item-id'];
console.log(item['$priority']);
console.log(item.title);
});
If you don't know the ID of your item, you can iterate over the $scope.items
object to find it if you'd like.
回答3:
As you've noted, your examples are a bit fragmented and there's also no example of your data structure to work from. So it's a bit hard to get a strong picture of what you're trying to accomplish. I'm going to make some assumptions below about all of these things and then offer a working example accordingly. If that doesn't answer the question, maybe it'll help us dig in and find the exact use case you're looking for.
Let's assume, for starters, that we have a list of users at kato.firebaseio.com/users, each of which is an object like so:
/users/:id/name
/users/:id/email
/users/:id/favorite_dessert
Now, let's assume I want to make those work with the following angularCode:
<ul>
<li ng-repeat="user in users">{{user.name}} really likes {{user.favorite_dessert}}</li>
</ul>
In my controller, I could put something like this:
var fbRef = new Firebase('https://kato.firebaseio.com/users');
$scope.users = $firebase( fbRef );
Now they will automagically appear in my HTML code.
Now, let's assume that when one of these users is clicked, I want to get a two-way binding, which can be edited in a form like this:
<form ng-controller="EditUserController">
<input ng-model="user.name" type="text" />
<input ng-model="user.email" type="text" />
<input ng-model="user.favorite_dessert" type="text" />
</form>
Inside EditUserController
I could obtain the user as follows:
var fbRef = new Firebase('https://kato.firebaseio.com/users/'+user_id);
$firebase( fbRef ).$bind($scope, 'user');
Or I could use $child
like this (purely to demonstrate usage of $child, not necessary):
var fbRef = new Firebase('https://kato.firebaseio.com/users');
// $child gives a new $firebase object! not a ref to a hash key!
$firebase( fbRef ).$child( user_id ).$bind($scope, 'user');
If I wanted to access any of this data programmatically inside my controller, I could do it like so:
var fbRef = new Firebase('https://kato.firebaseio.com/users');
var usersRef = $firebase( fbRef );
var userId = 'kato';
usersRef.$on('loaded', function() {
if( usersRef.hasOwnProperty(userId) ) {
// note that we just grab it by key; not $child!
var userRecord = usersRef[userId];
console.log(userId + ' was found, name is ' + userRecord.name + ' and priority is ' + userRecord['$priority']);
}
});
来源:https://stackoverflow.com/questions/20597581/a-little-clarity-on-getting-key-values-using-angularfire-v2