Есть ли Javascript-эквивалент Ruby's andand? - PullRequest
5 голосов
/ 08 января 2009

Пытаясь сделать мой Javascript ненавязчивым, я использую onLoad s, чтобы добавить функциональность к <input> s и тому подобное. С Dojo это выглядит примерно так:

var coolInput = dojo.byId('cool_input');
if(coolInput) {
  dojo.addOnLoad(function() {
    coolInput.onkeyup = function() { ... };
  });
}

Или, примерно эквивалентно:

dojo.addOnLoad(function() {
  dojo.forEach(dojo.query('#cool_input'), function(elt) {
    elt.onkeyup = function() { ... };
  });
});

Кто-нибудь написал реализацию Ruby's и , чтобы я мог сделать следующее?

dojo.addOnLoad(function() {
  // the input's onkeyup is set iff the input exists
  dojo.byId('cool_input').andand().onkeyup = function() { ... };
});

или

dojo.byId('cool_input').andand(function(elt) {
  // this function gets called with elt = the input iff it exists
  dojo.addOnLoad(function() {
    elt.onkeyup = function() { ... };
  });
});

Ответы [ 7 ]

3 голосов
/ 08 января 2009

Я не знаю Додзё, но разве ваш первый пример не должен читаться

dojo.addOnLoad(function() {
    var coolInput = dojo.byId('cool_input');
    if(coolInput)
        coolInput.onkeyup = function() { ... };
});

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

Вернуться к вашему вопросу: в JavaScript я бы реализовал andand() как

function andand(obj, func, args) {
    return obj && func.apply(obj, args || []);
}

Ваш пример может быть записан как

dojo.addOnLoad(function() {
    andand(dojo.byId('cool_input'), function() {
        this.onkeyup = function() { ... };
    });
});

, который на самом деле не намного короче, чем использование явного выражения if - так зачем беспокоиться?

2 голосов
/ 15 апреля 2009

Вы хотите dojo.behavior .

dojo.behavior.add({
    '#cool_input': {
        onKeyUp: function(evt) { ... }
    }
});
2 голосов
/ 15 апреля 2009

Точный синтаксис, который вы хотите, невозможен в JavaScript. Способ выполнения JavaScript должен был бы измениться довольно фундаментальным образом. Например:

var name = getUserById(id).andand().name;
//                        ^
//                        |-------------------------------
// if getUserById returns null, execution MUST stop here |
// otherwise, you'll get a "null is not an object" exception

Однако JavaScript не работает таким образом. Это просто не так.

Следующая строка выполняет почти то, что вы хотите.

var name = (var user = getUserById(id)) ? user.name : null;

Но удобочитаемость не подходит для более крупных примеров. Например:

// this is what you want to see
var initial = getUserById(id).andand().name.andand()[0];
// this is the best that JavaScript can do
var initial = (var name = (var user = getUserById(id)) ? user.name : null) ? name[0] : null;

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

var name = (function() {return (var user = getUserById(id)) ? user.name : null;})();

Теперь пользовательская переменная очищена правильно, и все счастливы. Но вау! как много печатать! :)

1 голос
/ 08 января 2009

Как насчет этого:

function andand(elt, f) {
  if (elt)
    return f(elt);
  return null;
}

Звоните так:

andand(dojo.byId('cool_input'), function(elt) {
  // this function gets called with elt = the input iff it exists
  dojo.addOnLoad(function() {
    elt.onkeyup = function() { ... };
  });
});
0 голосов
/ 15 апреля 2009

Для списка:

Array.prototype.andand = function(property, fn) {

    if (this.filter(property).length > 0) this.map(fn);
}
0 голосов
/ 08 января 2009

Я никогда не использовал dojo, но большинство фреймворков javascript (при работе с DOM) возвращают вызывающий элемент при вызове метода из объекта элемента (плохая формулировка, извините). Поэтому andand () будет неявным.

dojo.addOnLoad(function() {
  dojo.byId('cool_input').onkeyup(function(evt) { /*event handler code*/
  });
});
0 голосов
/ 08 января 2009

Насколько я знаю, нет встроенной функции JavaScript с такой же функциональностью. Я думаю, что лучшее решение - это запрос по классу вместо id и использование dojo.forEach (...), так как вам гарантирован ненулевой элемент в закрытии forEach.

Вы всегда можете использовать эквивалент JavaScript:

dojo.byId('cool_input') && dojo.byId('cool_input').whateverYouWantToDo(...);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...