Firebase.push не удалось: первый аргумент содержит недопустимый ключ ($$ hashKey)
Недавно я начал изучать AngularJS + Firebase. Я пытаюсь написать в своей firebase объект вроде этого:
{
title: "Personal Information",
say: [
[{ "eng": "What's", "ukr": "Що є" }, { "eng": "your", "ukr": "твоє" }, { "eng": "surname?", "ukr": "прізвище?" }],
[{ "eng": "Smith", "ukr": "Сміт" }],
[{ "eng": "What's", "ukr": "Що є" }, { "eng": "your", "ukr": "твоє" }, { "eng": "first", "ukr": "перше" }, { "eng": "name?", "ukr": "ім'я?(не фамілія)" }]
]
}
с линией:
lessondata.add($scope.topic);
где "lessondata" - это сервис, созданный с помощью angularFireCollection() и $scope.topic - объекта, привязанного к моему пользовательскому интерфейсу.
Но получил следующую ошибку:
Firebase.push не удалось: первый аргумент содержит недопустимый ключ ($$ hashKey) в свойстве "say.0.0". Ключи должны быть непустыми строками и не содержать ".", "#", "$", "/", "[", Или]]
Как я понял, Firebase не позволяет использовать 0 в качестве ключа, даже если это ключ в прикрепленном массиве, для которого нулевой ключ является естественным. Так что я должен изменить структуру объекта в некотором жестком закодированном экземпляре, или я что-то пропустил? Спасибо заранее!
Ответы
Ответ 1
EDIT: Как отмечает Anant в комментариях, в последней стабильной версии Angular (1.0.7 atm) вы можете использовать angular.copy(obj)
для удаления атрибутов $$hashkey
.
Как сказал Майкл, "$" в "$$ hashKey" - проблема. Angular создает свойства $$hashkey
за кулисами (подробнее см.: https://groups.google.com/forum/#!topic/angular/pI0IgNHKjxw). Я обошел эту проблему, выполнив что-то вроде myRef.push(angular.fromJson(angular.toJson(myAngularObject)))
.
Ответ 2
Проблема заключается в $in "$$ hashKey", а не 0. 0 разрешено.
Ответ 3
Я хотел добавить другой ответ, который намного проще, просто используйте track by
в своем повторении. Он избавится от атрибута $$hashKey
, который вызывает столько горя.
<div ng-repeat="item in items track by $index">{{item.name}}</div>
Ответ 4
Я немного опаздываю на это, но я думал, что хотел бы добавить свои два цента, когда я качал головой по всем остальным ответам. Надеюсь, это поможет вам избежать этой проблемы.
Используйте библиотеку angularFire, предназначенную для обработки данных angular и используйте ее методы.
тогда как вы можете использовать чистые методы библиотеки javascript для .push() .add() .update()
, .set()
ect.
Итак, если вы хотите избежать любых столкновений, когда firebase связывается с angular javascript , вам нужно использовать соответствующие методы .$foo()
(т.е. .$save()
). В вашем случае просто добавьте $
к вашему .add()
(сделайте это .$add()
)
поэтому используйте lessondata.$add($scope.topic);
при сохранении с помощью firebase vs angularfire
Метод AngularFire $save()
реализуется с использованием метода Firebase set()
.
Операция Firebase push()
соответствует методу AngularFire $add()
Обычно вы должны использовать set()/$save(), если у вас либо есть объект, который уже существует в базе данных, либо если вы работаете с объектами с естественным ключом.
подробнее об этом здесь: fooobar.com/questions/309069/...
Что нужно отметить с помощью AngularFire
Для обратного вызова:
и если вы хотите, чтобы обратный вызов знал, правильно ли сохранены ваши данные, вы можете сделать что-то вроде этого:
var list = $firebaseArray(ref);
list.$add({ foo: "bar" }).then(function(ref) {
var id = ref.key();
console.log("added record with id " + id);
list.$indexFor(id); // returns location in the array
});
Я был удивлен, что это не упоминалось ранее ни в одном из других ответов, но посмотрите на эти документы https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebasearray-addnewdata
Приветствия.
Ответ 5
Вы также можете отключить свойство, прежде чем нажимать его.
delete $scope.topic.$$hashKey
Ответ 6
Лучший способ избавиться от $$ hasKeys - использовать "track by" в ng-repeat, как в следующем (как упоминалось выше)
<div ng-repeat="(key, value) in myObj track by $index"> ... </div>
но вы также можете установить дорожку как параметр параметров ng-model
ng-model-options="{ trackBy: '$value.someKeyOnYourObject' }"
для управления формой. Этот способ также улучшает производительность вашего приложения angular.
Другой способ - удалить $$ hashKey с помощью
angular.copy(someObj);
Если все остальное не удается, вы также можете использовать lodash для удаления ключей, начинающихся с "$".
_.omitBy(yourObject, function(value, key){return _.startsWith(key, '$');});