Массивы Javascript и Метеорная сессия
Я сделал интересное наблюдение. При попытке обновления массива, хранящегося в хранилище сеансов Meteor, следующий код не будет распространять изменения:
var tags = Session.get("Tags");
tags.push("a");
Session.set("Tags", tags);
Но если я изменил первую строку на использование Session.get("Tags").slice()
, все, что зависит от сеанса, будет соответствующим образом обновляться. Я предполагаю, что это связано с тем, что Meteor проверяет некоторые ссылки на равенство и, следовательно, ничего не обновляет.
Есть ли лучший способ управлять списками, хранящимися в хранилище сеансов метеоритов?
Если я сейчас попытаюсь удалить элемент из коллекции (используя array.remove()
из здесь), поведение оказывается немного... из... Я делаю это внутри события шаблона Meteor, код выглядит следующим образом:
"click .taglist li" : function(e) {
var tags = Session.get("Tags").slice();
var index = cardTags.indexOf(this);
Meteor._debug(Session.get("Tags").slice().indexOf("a"));
Meteor._debug("Removing tag \"" + this + "\", index: " + index, ", typeof(this) = " + typeof(this).toString());
tags.remove(index);
Session.set("Tags", tags);
}
Выводится:
1
Removing tag "a", index: -1, typeof(this) = string
Итак, как-то оператор cardTags.indexOf(this);
, кажется, возвращает -1
практически для любого случая. Я думаю, что я делаю что-то принципиально неправильное, так как теперь я достаточно разбираюсь в javascript, но почему-то не могу понять, что происходит здесь.
Почему эти два вызова indexOf() ведут себя иначе?
Ответы
Ответ 1
Я считаю, что это так же, как эта ситуация в Backbone.js. Чтобы инициировать событие изменения, Meteor должен иметь новую ссылку для массива, а не только обновленную копию старого.
Вкратце, чтобы иметь "правильное" поведение, вам нужно клонировать массив, вносить нужные изменения, а затем выполнять Session.set('foo', myCopiedArray).
Ответ 2
Короче: Вместо этого используйте var index = cardTags.indexOf(this.toString());
.
Длинная версия:
При использовании строк в JavaScript это строки, тогда как typeof 'test'
возвращает string
.
Посмотрим на следующий код, чтобы узнать другой способ представления строк в JavaScript:
var func = function () {
return this;
};
console.log(func.call('test'));
Консоль (по крайней мере, FireBug) не покажет нам "test"
, но вместо этого отобразит String {0="t", 1="e", 2="s", 3="t" }
. typeof
вернет "object"
.
Содержимое оператора this
, по-видимому, должно быть объектом. Чтобы преобразовать строку в объект "String", мы можем сделать console.log(new String('test'));
, что совпадает с ранее зарегистрированным значением.
Чтобы преобразовать строковый объект в строку (тип данных), просто используйте его прототип toString
.