Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

[ns.model] Метод get() должен всегда возвращать массив результатов #170

Closed
doochik opened this Issue · 22 comments

4 participants

@doochik
Owner

Я уже много про это говорил, но давайте еще раз.

Я уже много раз натыкаюсь и меня удручает разные типы ответов.

{
  "cnt": 10
  "arr": [
    {"id": 1, "cnt": 1} ,
    {"id": 2, "cnt": 2} 
  ]
}

this.get('.cnt') -> 10
this.get('.arr[.id == 1].cnt') -> [1]
this.get('.arr[.id == "нет такого"].cnt') -> undefined (???).

Т.е, чтобы реализовать правильный выбор по id, мне после get приходится писать if (result). Неудобство раз.

Почему в первом случае массив, во втором - нет? Да, есть правило, если jpath проходит через массив, то результат будет массивом. Получается я еще и структуру данных должен в голове держать. Неудобство два.

Мое предложение: this.get всегда возвращает массив выбранных результатов. Т.е.
1) [10]
2) [1]
3) []

Профиты:
1) не надо знать структуру данных
2) всегда единый формат результатов
3) улыбка и счастье на лицах разработчиков

@doochik doochik was assigned
@chestozo
Owner

Вот ведь, я почти не пользовался до сих пор этим...
Но +1 к предложению.

@edoroshenko
Owner

Полуночная идея:

  • метод get возвращает ту структуру данных, которую он нашёл по jpath
  • метод find всегда возвращает массив
@doochik
Owner

это хороший компромисный вариант, но кмк все равно все будут использовать find

@edoroshenko
Owner

Нет. Если ты примерно представляешь, что у тебя в этом поле примитив, то ты будешь использовать get.
Запись model.get('.isEditable')[0] выглядит более, чем странно

@chestozo
Owner

Может быть нам нужен select(), который вернёт массив? )

@edoroshenko
Owner

типа это не поиск, а выборка?
no.jpath.select(src, '.path.to.node')
Вроде выглядит ровно

@doochik
Owner

У меня вот такая обертка

qu.jpath = function(jpath, data) {
    return no.jpath.raw(jpath, data).toArray();
};

И нет, когда сделаем этот метод, я никогда не будут использовать .get, потому что не хочу разбираться с проблемами при каких-то изменениях в данных, а тем более держать в голове форматы данных. Но это уже вкусовщина.

@chestozo
Owner

2 @doochik:
И тебя не будет парить вот так писать model.get('.isEditable')[0]?

Ещё вот идейничаю — может так:

model.val('.isEditable');
model.select('.items.item');
@edoroshenko
Owner

Я не исключаю, что мы тоже перестанем использовать .get. Давай попробуем сделать 2 метода и пожить так.

@chestozo
Owner

Давай попробуем сделать 2 метода и пожить так.

Какие? )

@edoroshenko
Owner

get и find
или val и select
или get и select

@doochik
Owner

Давайте get() и select() ?

@edoroshenko
Owner

Я за

@edoroshenko
Owner

Лёш, а ещё такой вопрос: мы можем что-то сделать, чтобы get по this.get('.arr[.id == 1].cnt') возвращал не массив?
Или мы фиксируем правило, что если в jpath есть предикат, то нам возвращается массив?

@pasaran
Owner

Там на самом деле сейчас так.
Есть основная функция no.jpath.raw — она возвращает либо инстанс no.JNode, либо no.JNodeset.
Первый вариант случается только если по пути выполнения jpath'а не нужно было создавать массив. Ну то есть примерно:

data = {
    foo: {
        bar: 42
    }
};

no.jpath('.foo.bar', data)

Если есть предикат, то всегда нужно создавать JNodeset. Для консистентности — для любых данных один и тот же jpath должен возвращать результат с одним типом.

А потом уже результат разворачивается вот таким методом:

no.jpath.toScalar = function(result) {
    if (result instanceof JNode) {
        return result.data;
    } else if (result instanceof JNodeset) {
        return ( result.isEmpty() ) ? undefined : result.toArray();
    } else {
        return result;
    }
};

(название toScalar тут не очень правильное, надо бы что-то типа toValue, toResult, ...)
Если ты уверен, что у тебя там всегда один элемент, ну сделай обертку какую-нибудь для такого случая.

@doochik
Owner

@edoroshenko это еще одна причина почему я всегда хочу массив )

@pasaran
Owner

потому что не хочу разбираться с проблемами при каких-то изменениях в данных, а тем более держать в голове форматы данных. Но это уже вкусовщина.

По факту, Леша, ты таки разбираешься. В одном месте ты по результату итерируешься, а в другом делаешь [0]. Поэтому на самом деле в большинстве случаев ты просто впустую заворачиваешь значение в массив, а потом достаешь из него первый элемент.

@doochik
Owner

Нет, если я пишу [0] - это означает, что мне нужен первый. Даже если там будет 2, я сознательно беру первый.
Если я пишу .forEach, то хочу всю выборку и мне должно быть без разницы сколько там элементов, 0 или 100.

@edoroshenko
Owner

Вобщем, принцип работы с get можно сформулировать так:

Если делаешь простые выборки без предикатов из известной структуры данных, используй `get`.
Если работаешь с непредсказуемой структорой данных или хочешь предикат - используй `select`.
@chestozo
Owner

А нельзя сделать так:
get всегда возвращает один элемент (сам объект или первый элемент из коллекции)
select всегда возвращает массив?

@edoroshenko
Owner

и методы называются get и getAll )

@doochik doochik closed this in e896608
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.