Pull to refresh

Comments 30

Если бы речь была только об элементах, можно было бы проще:
elements: {
	name: '.someSelector'
},
// и потом обращаться вот так:
this.$name.blahBlah()

Написать метод _ensureElements, который обходит _.result(this, 'elements') дело пяти минут. Но у вас есть и другие интересные идеи, молодцы.
Использование подобных деклараций становится не очень удобным, когда вы начинаете наследоваться.
Всяко веселее, чем писать this.someThing = this.$('.js-someThing') стопицот раз. А что до наследования, то _.result помогает, а то и вот такой метод.
Я не говорил, что this.someThing = this.$('.js-someThing') это круто.
Я имел в виду, что предпочитаю метод, возвращающий результат, подобным объектам в прототипе.
Метод по ссылке — выход, но, на мой взгляд, способ позвать реализацию в родителе должен быть один — что-нибудь вроде backbone-super.
А вы не в курсе что View#events, Model#defaults, Collection#url и многое другое может быть либо методом, либо объектом? Это очень удобно, потому что иногда проще написать объект, чем городить метод, который возвращает литерал. Такой же принцип и тут.

Приведенный вами плагин мне не нравится из-за того, как именно он это делает. Лучше уж чуть более многословно, зато без черной магии и с внятным стектрейсом в случае чего.
Я в курсе, но, повторюсь, предпочитаю всегда использовать метод.
иногда проще написать объект, чем городить метод

Вы так говорите, как будто метод вместо объекта — это очень сложно или долго.

Суть не в том, как именно звать родительскую реализацию, а в том, чтобы всегда делать это одинаково.
> это очень сложно или долго
Нет, не очень. Пока у вас 5 вьюх, не проблема:) В подавляющем большинстве случаев нужное свойство статично и его можно написать литералом. Если всегда писать только методы, то получится куча методов, которые ничего не делают, только тупо возвращают строку или хэш. Выглядит это не очень.
Не понял, как связан выбор между объектом и методом, возвращающим объект, с количеством вьюх.

Зато понимаю ваше стремление к красивому коду. Просто предпочитаю однообразие.
Напрямую. Чем больше кода, тем меньше хочется писать шаблонных вещей типа
events: function () {
    return {
        'click': 'toggleClicked'
    } 
} 
3 раз такое можно написать, на 4 пойдешь и поменяешь поведение в общем предке.
Вы в каком редакторе код пишите?

Я предпочитаю IDE от JetBrains, там есть Live Templates:
Набираете несколько символов, нажимаете Tab — и шаблонный код готов. Я даже видео для вас записал.

В вашем любимом редакторе, наверняка, тоже есть что-то подобное.

Писать легко, единообразие во всех файлах достигается без усилий.
Я в лесу живу и пишу код острой намагниченной иглой, конечно же.
Серьезно, если для вас основная проблема шаблонного кода — что его трудно напечатать, то я не вижу смысла в дискуссии.
Все, что повторяется — это декларация метода и суперколл. Я не вижу удовлетворительного способа избавиться от шаблонного кода в этой ситуации.

Буду рад, если предложите таковой.
Так я же говорю — писать литералы там, где не нужно менять свойство в рантайме.
А когда вы захотите наследоваться и что-то переопределить — вам придется менять литерал на метод в родительском классе или использовать особый способ вызывать родительский метод, умеющий обрабатывать ситуацию, когда выше по цепочке — литерал. Вот этот момент мне кажется важным.
Ну, я для себя выработал то самое решение по ссылке. Можно туда еще сахарку добавить, в принципе.
Доктор, меня все игнорируют.
Код, про который идет речь в статье, используется в нескольких проектах, где есть сотни вьюшек. Каждый раз думать о том свойство где-то или метод реально напрягает.
Меня не устраивает это решение.
1. Если мы его используем только там, где бывают литералы — то у нас возникает два разных способа вызвать родительский метод. Не круто.
2. Если мы его используем везде — то везде постоянно будет проверяться, функция или нет выше по цепочке. Тоже не круто.

Я думаю, можно прекратить обсуждение. Я вас понимаю, вы меня, наверное, тоже.
Да, я понял: вы зачем-то смешиваете соглашение по определению свойств в Backbone и родительские методы.
Что же до вызова родительских методов — увы, ждем ES6.
Иногда статичное свойство может измениться, и тогда придется искать его, и править по всему проекту. А в случае с методом, придется изменить свойство только внутри метода, который его возвращает.
Спасибо за минусы, приму их как знак внимания. Обосную тем кому все таки интересно. Во-первых плохой тон обращаться к свойствам напрямую — это одно из фундаментальных правил программирования. Например, тут или тут тут мнение авторитетов. Во-вторых, работать можно не только в одиночку — и когда работаешь в команде, то сложно отвечать и контролировать чужие действия, а если команда находится в разных городах, а то и часовых поясах, то еще сложнее. Поэтому если ты используешь чье-то свойство, то лучше избегать прямого обращения к нему, а пользоваться геттерами и сеттерами, потому-что «хозяин свойства» в любой момент может что-то изменить или зарефакторить и в этом случае, он не обязано спрашивать чье-то мнение. Сюда же можно добавить то, что даже когда сам начинаешь проект, то должен понимать, что статика может меняться много-много раз, и для того чтобы не править всё и везде, легче править в двух местах — в геттере и сеттере.
А что вы, простите, предлагаете? поменять название свойства, но оставить старые названия акцессоров?
getPrice: function () { return cost; } // srsly, wtf

Ну а если переименовать акцессоры, то их по любому надо будет везде переименовывать, неважно, plain это свойство или геттер-сеттер.

Я в принципе не против акцессоров, это полезно. Только рефачить одинаково. А чтобы не болело, надо использовать IDE с поддержкой рефакторинга.

P.S.
jQuery — далеко не образец безупречной архитектуры и API, кстати. Если бы это было не так, мы б не писали комменты под статьей под названием «как разгрести говнокод из джейквери».
this._elem(‘item’, {
  mod: ‘state’,
  value: ‘focused’
});

Чтобы найти элементы с несколькими модификаторами придется писать массив?
А не проще ли тогда сделать ключ значение?

{
    state: 'focused'
}
Это довольно редкая ситуация, а если надо искать элементы по нескольким селекторам, то можно сделать, например, так:
_selectors: function () {
  return {
    someCollection: '.selector1, .selector2'
  };
}

а потом в коде
this._elem('someCollection');

Как вариант:

//где-нибудь в базовой вьюхе функция которая является и сеттером и геттером. 
frg: function (name, el) {
	!this.domElements && (this.domElements = {});
	return el ? (this.domElements[name] = el, el) : this.domElements[name];
}


// Использование наследуемых вьюхах: 

// в сеттер надо передать два параметра: название и сам элемент. 
// сеттер так же возвращает закешированный элемент
this.frag('my-block',  this.$('#my-block')).css({display: 'block'});

// геттер получает один аргумент и возвращает из кеша элемент
this.frag('my-block').css({display: 'block'});

Довольно стройно и элегантно
Прощу прощения за опечатку: Надо либо в базовой вьюхе назвать метод frag, либо в наследуемых вызывать как this.frg()
Sign up to leave a comment.

Articles