У меня очень мало опыта работы с Backbone, но я унаследовал код другого разработчика для поддержки. Я пытаюсь добавить в модель какой-то новый функционал. Вот что у меня есть на данный момент:
var AfeDetailCollection = Backbone.Collection.extend(
{
model: AfeDetailModel,
getSubtotalUSD: function(){
return _.reduce(this.models, function(memo, model, index, list){
return memo + model.getExtCostUSD();
}, 0, this);
},
getSubtotalLocal: function () {
return _.reduce(this.models, function (memo, model, index, list) {
return memo + model.getExtCostLocal();
}, 0, this);
},
hasMixedCurrency: function () {
var currCode = '';
this.models.each(function (model) {
if (currCode == '')
// Identify the currencyCode of the first AfeDetail object in the collection
currCode = model.get('currencyCode');
else if (currCode != model.get('currencyCode'))
// The currencyCode has changed from prior AfeDetail in the collection
return true;
});
return false;
}
}
);
Я добавил функцию hasMixedCurrency (). Две ранее существовавшие функции работают нормально. Я пытаюсь определить, содержит ли коллекция объектов AfeDetail несколько значений currencyCode (свойство модели AfeDetail). Итак, я просто пытался перебирать эту коллекцию, пока не нашел изменение в currencyCode, а затем вернул true.
Однако в javascript на моей странице, как только я попытаюсь это проверить ...
if (this.collection.hasMixedCurrency()) {
...
... Я получаю это: Ошибка: объект не поддерживает свойство или метод "каждый"
Я явно что-то делаю не так, наверное, что-то простое, но я этого просто не вижу.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Похоже, что this.models - это массив javascript, а не сборник позвоночника.
Вы можете попробовать каждый метод подчеркивать:
_.each(arr, function(val) {
});
Также ваша логика в цикле выглядит неправильно. Попробуйте этот код:
hasMixedCurrency: function() {
return _.size(_.uniq(this.models, "currencyCode")) > 1;
}
Edit: More performanced way
hasMixedCurrency: function () {
return _.find(this.models, function(v) { return v.currencyCode !== _.first(this.models).currencyCode; }) !== undefined;
}
Это массив JavaScript, в котором нет метода each. Кстати, если бы это была коллекция, each работал бы, потому что у него есть метод each.
Да, ты прав. Я ошибся при написании. Прошу прощения.
Думаю, мне нужно вникнуть в это подробнее, чтобы понять разницу между массивом JS и коллекцией Backbone. В любом случае, ваш образец кода сделал свое дело! @ibrahimyilmaz
На самом деле, при ближайшем рассмотрении этот код работает не так, как надо. Он каждый раз возвращает True. Он должен возвращать значение true только тогда, когда массив содержит более одного значения currencyCode. Я продолжу играть с этим.
Да, @PongGod, ты тоже прав :) Проверьте мой отредактированный ответ и попробуйте скрипт выше.
Когда я запускаю вашу скрипку, я ничего не вижу. Кстати, я начал использовать другой подход, который, как я думал, сработает, но его еще нет. Возможно, вы можете взглянуть и сообщить мне, что вы думаете: jsfiddle.net/PongGod/6qvz2p94/3
На самом деле, простая корректировка кода делает все правильно: return .размер(.uniq (this.models, "currencyCode"))> 1; Нет необходимости сравнивать размер массива. Проще говоря, если в массиве появляется более одного значения currencyCode, оно должно возвращать true. Если вы можете соответствующим образом отредактировать приведенный выше код, я приму это как правильный ответ.
Ты неправ. Функция _.uniq возвращает тот же массив без повторяющихся значений. Итак, размер _.uniq () для array1 и array2 равен 3. Снова посмотрим на скрипку, сейчас я пишу в html.
Также ваша рабочий пример недействительна. Нельзя сравнивать только первое и последнее значения массива. Двойные значения могут быть посередине.
Что касается моей скрипки, возможно, вы не заметили, что я отсортировал значения перед сравнением. Пример работает, но, к сожалению, у меня возникли трудности с его успешной адаптацией к моему приложению. Однако, когда я изменил ваш код, как я описал, он начал работать правильно. Что касается вашей обновленной скрипки, я не вижу вывода в разделе консоли. В любом случае все три массива содержат смешанные валюты, поэтому я не уверен, как это доказывает, что это работает. Конечно, я могу отредактировать один из них, чтобы включить только одну валюту, но я все еще не могу увидеть результат, когда я его запускаю.
Я добавил скриншот экрана jsFiddle. В любом случае, ваша рабочий пример все еще не права, попробуйте подумать об этом.
Логика в моей скрипке не ошибочна. Если у вас есть массив строк и вы отсортируете их в алфавитном порядке, сравните первое и последнее значения и обнаружите, что они совпадают, то вы с уверенностью знаете, что между ними нет различающихся значений. В любом случае, я уже отказался от этого подхода в пользу вашего с небольшой модификацией, которую я описал, и она работает. Я очень признателен за вашу помощь и с радостью отмечу его как решение, если вы обновите его соответствующим образом. В нынешнем виде этот код не работает для меня как решение.
Кстати, твоя рабочий пример - это не та рабочий пример. Все три из этих примеров массивов должны возвращать True, потому что все они имеют смешанные валюты. Если, например, одно из значений включало только «USD», то оно должно вернуть False. Возможно, вы неправильно поняли мои требования, но я думаю, что объяснил это довольно ясно.
Прошу прощения за недоразумение, я думал, вы хотите найти повторяющиеся значения. Ты прав.
Если вы измените свой ответ выше на: .size (.uniq (this.models, "currencyCode"))> 1; Я могу принять это как решение. Спасибо!
Я отредактировал его и добавил более добрый (высокопроизводительный) метод. Нам не нужно делать массив уникальным.
Позвольте нам продолжить обсуждение в чате.
Нет такого метода под названием
eachдля массива JS afaik ... попробуйтеthis.each,thisявляется ссылкой на коллекцию.