Подтвердить что ты не робот

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 в качестве ключа, даже если это ключ в прикрепленном массиве, для которого нулевой ключ является естественным. Так что я должен изменить структуру объекта в некотором жестком закодированном экземпляре, или я что-то пропустил? Спасибо заранее!

4b9b3361

Ответ 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, '$');});