• Почему неправильно считает JQuery, где ошибка?

    @Quilin
    Full-stack разработчик
    1. Оптимизируйте селекторы.
    #valmovaya #area-h1 - вот это плохой селектор, потому что он ищет по идентификатору внутри элемента с идентификатором, но вторая часть уже лишена особого смысла, поскольку первый идентификатор по определению и так уникален. Оставьте просто #area-h1. А еще лучше вообще уберите из идентификатора указатель на название тега, это архидурной тон.

    2. val возвращает строковое значение. Работать со строками как с числами - очень плохая затея, даже в языках с динамической типизацией. Либо пользуйтесь parseInt(vaml_h1), либо вообще кастом в духе +valm_h1.

    3. jQuery не считает, арифметические расчеты это зона контроля JavaScript.

    Любой из этих трех вариантов вам подойдет, в принципе.
    var valm_w1 = +$("#area-w1").val();
    var valm_w3 = parseInt($("#area-w3").val());
    var valm_h1 = parseFloat($("#area-h1").val());
    Ответ написан
  • Сложная бизнес-логика. Как всё учесть?

    @Quilin
    Full-stack разработчик
    В очень плотно и сложно связанных системах, подобно описанной, хорошо работает паттерн ActorModel. Идея состоит в том, что ваш код разделен на огромную кучу крошечных подпрограмм, каждая из которых умеет
    - выполнять атомарные действия
    - отправлять сообщения другим акторам
    - создавать новые акторы

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

    Что касается вашего конкретного кейса, у меня создалось впечатление, что вас скорее интересует работа с единым хранилищем данных игровых объектов. Для этого тоже есть масса интересных решений, например Unidirectional Data Flow.
    Хранение состояния игры в одном единственном месте, обращение к нему через прослойки-мапперы. Есть несколько вариантов реализации перехвата изменений - это может быть иммутабельное состояние, для которого достаточно будет считать дельту между старым и новым, публикуя изменения глобально, так чтобы участки программы, которым эти изменения интересны, сами их подхватывали, либо реактивное состояние, которое запоминает, кто к ней обращался за какими данными и уведомляет их о конкретных изменениях непосредственно в момент их применения.

    Разумеется, для сложной игровой механики, совершенно необходимо писать и поддерживать юнит- и интеграционные тесты. С тестированием вы избежите огромной кучи багов, например пресловутого "если я это где-то забуду".

    Но в любом из этих случаев, как грамотно сказал один программист: "Архитектуру легко придумать сложной", имея в виду, что нужно стремиться ее упрощать.
    Ответ написан
    Комментировать
  • Как переписать require в import?

    @Quilin
    Full-stack разработчик
    import googleClientApi from 'google-client-api'
    
    googleClientApi(function (gapi) { /* lalala */ })
    Ответ написан
    Комментировать
  • Как транспонировать матрицу не используя циклы?

    @Quilin
    Full-stack разработчик
    В JavaScript не существует двумерных массивов, по сути матрица будет "вектором векторов". Обращение к элементу по его индексам будет выглядеть как-то так: myMatrix[i][j].

    Транспонирование матрицы в этом контексте вообще не имеет никакого смысла, ведь для этого достаточно просто поменять местами i и j. Я бы посоветовал написать фасад над работой с массивом, например так:

    class Matrix {
      constructor (arr, transposed) {
        this._arr = arr
        this._transposed = !!transposed
      },
    
      get (i, j) {
        return this._transposed
          ? this._arr[j][i]
          : this._arr[i][j]
      },
      transpose () {
        return new Matrix(this._arr.map(row => row.slice()), true)
      }
    }
    
    var matrixA = new Matrix([[1,2],[3,4],[5,6]])
    matrixA.get(1, 0) // 3
    var matrixB = matrixA.transpose()
    matrixB.get(0, 1) // 3


    Обратите внимание на то, что при транспонировании матрицы важно копировать содержимое служебного массива, в противном случае данные, модифицированные в оригинальной матрице будут отражаться и в транспонированной матрице.
    Ответ написан
    Комментировать
  • Нормальный ли это подход к организации JS код?

    @Quilin
    Full-stack разработчик
    Этот подход "псевдоооп", хотя у вас и есть какие-то объекты, вы лишаете себя целой кучи полезных вещей - наследования, полиморфизма, не очень оптимально работаете с памятью.

    В JS ооп принято варить через прототипы. Например, вот так:

    (function (my) {
    my.Form = function () {
      $(document).on('submit', 'form', function (evt) {
        // это же просто пример, так?
      });
    };
    my.Form.prototype.submit = function () {
      // ...
    };
    })(MY);


    В дальнейшем, если вам понадобится не просто форма, а, например, валидируемая форма, или даже AJAX-форма, вы сможете без проблем отнаследоваться от этой формы и добавить ништяков. Например.

    (function (my) {
    my.ValidatedForm = function () {
      // something
    };
    my.ValidatedForm.prototype = new my.Form();
    my.ValidatedForm.prototype.isValid = function () {
      // ...
    };
    })(MY);


    Также у вас появится доступ к состоянию инстанса через ключевое слово this: для этого потребуется создавать экземпляры через оператор new. Будет выглядеть как-то так:

    var myForm = new MY.Form();
    myForm.submit();


    Это не всегда нужно делать именно так, но все зависит только от того, чего вы в конечном счете пытаетесь достичь. Я очень советую почитать статьи Ильи Кантора, автора сайта javascript.ru про ООП в JS. Он прилично пишет и хорошо разбирается в предметной области.
    Ответ написан
    1 комментарий
  • Минимальные версии браузеров?

    @Quilin
    Full-stack разработчик
    Все зависит от бизнес-требований и особенностей аудитории. Скажем, онлайн-бухгалтерией нередко пользуются на госпредприятиях, где переставлять пиратскую XP никто не станет, или просто на крупных, где никто не станет тратиться на массовую закупку "семерок" и иже с ним. Но такие клиенты могут приносить бизнесу большую часть дохода - и в итоге верстают под ie8-, увы.
    В прочих ситуациях можно отказываться от поддержки старых браузеров в стиле "да ну их нафиг".

    Есть еще и третий вариант, как по мне так золотая середина - graceful degradate. Наша задача в верстке состоит в том, чтобы вебсайт работал и позволял выполнять основные бизнес-сценарии, но в старых браузерах он будет выглядеть тем хуже, чем старше браузер. Возможные проблемы с js призваны решать различные modernizr'ы, а верстку достаточно делать для "молодых" браузеров.

    Помнится, лет десять назад можно было встретить сайты, на главной странице которых возникал алерт "Сайт оптимизирован для расширения экрана 1024х768". Так делать, конечно, не надо =)
    Ответ написан
    Комментировать
  • Разработчики ASP.NET, как вы пишете личные проекты?

    @Quilin
    Full-stack разработчик
    По первым пунктам сказано достаточно и довольно точно, по последнему - сам в настоящее время пользуюсь линуховой VPS, на которой ASP.NET MVC проект развернут при помощи Mono под Nginx с PgSql и MongoDb. Все работает очень стабильно, реплики реплицируются, соединения соединяются.
    Ответ написан
    Комментировать
  • Как двойной знак равенства влияет на строки в С++?

    @Quilin
    Full-stack разработчик
    Простой знак равенства в C-подобных языках - это оператор присвоения. Как правило, он возвращает результат присвоения. Двойной знак равенства - это оператор сравнения, и возвращает он bool.

    Собственно, в условном операторе необходимо, чтобы выражение в скобках после ключевого слова if возвращало именно bool, так что простое присвоение в данном случае не сработает. Поэтому и нужен двойной знак равенства.

    В вашем конкретном коде очевидно, что вам знакома операция присвоения (len = len + 1), но в этом случае достаточно воспользоваться операцией инкремента (len++).
    Ответ написан
    Комментировать
  • JQuery: попытка #2. Как реализовать функцию?

    @Quilin
    Full-stack разработчик
    Попробуйте

    showOnly = function (cat) {
        return function (evt) {
            $(this).addClass('active');
            worksAll.hide();
            cat.show('fast', function () { cat.appendTo('.works-flow'); });
        };
    };


    А еще поузнавайте про делегаты в JavaScript.
    Ответ написан
  • На чем писать чат?

    @Quilin
    Full-stack разработчик
    Протокол - это контракт взаимодействия между клиентом и сервером. Он может быть совершенно любым, коль скоро вы пишете и приложение-клиент, и сервер самостоятельно. Можно при желании вообще свой протокол написать. Только, конечно, изобретать велосипед особо смысла, пожалуй нет. Что касается MT Proto от Telegram, он, конечно, достаточно безопасный, но чтобы его использовать нужны определенные требования. Я бы советовал не изобретая велосипед и не гоняясь за модными решениями взять что-то простое, типа HTTP(S) и использовать его. А если что-то на этом протоколе реализовать не получится, тогда уж вы и сможете в полной мере назвать причины перехода на другие протоколы.

    Что касается готовых решений для чата - они, несомненно, существуют. Надо просто погуглить.

    Что касается среды разработки - она целиком зависит от выбранного вами языка. Xamarin, например, позволит вам и под ios, и под андроид писать на C#. Для C# лучшая среда - Visual Studio. Если будете писать на Java - там свои JetBrains тулзы.

    Надо просто хорошо понимать, что конкретно вы хотите сделать, и что вы подразумеваете под масштабированием. Шардинг/репликация базы данных? Количество активных коннекций?
    Ответ написан
    Комментировать
  • Как организовать поиск внутри дочернего элемента первого уровня?

    @Quilin
    Full-stack разработчик
    Попробуйте:

    var inputs = $(".control-group .control-group input").not(".control-group .control-group .control-group input");

    Не самое оптимальное решение, но хоть так. А вообще говоря, я бы рекомендовал вам пометить нужные вам инпуты своим классом. Если они генерируются на сервере, это будет проще простого, если на клиенте - не менее просто, а если вы их пишете руками - то тогда вообще задача становится тривиальной. Тогда вам достаточно будет выбирать их как-нибудь $(".control-group-input") так.
    Ответ написан
    Комментировать
  • Есть альтернативы БЭМ?

    @Quilin
    Full-stack разработчик
    Странное ощущение, что это троловопрос. Тем не менее.

    Вы же понимаете, что методология БЭМ именования классов касается лишь постольку поскольку? Никто из тех, кто пользуется БЭМ в жизни не пишет все эти названия классов вручную, код на выходе может быть тяжеловесным, но та его часть, с которой работает разработчик - лаконичная и адекватная. Хотя, конечно, это зависит от вашего навыка проектирования и разработки. В самом Яндексе, уверяю, далеко не всегда код симпатичный и удобный.

    Если вы собрались переводить ваш сайт с одного подхода на другой, вы так или иначе встанете перед дилеммой: переписывать все или переписывать не все. Другой вопрос, что двойственный подход может стоить вам куда больше полной переписки.

    Исключительно в ваших силах не превращать все в выгребную кучу. Я, например, пользуюсь совершенно тривиальным подходом в верстке, который на достаточно серьезных проектах так и не скатился в тартарары.
    1. Побольше частичных представлений данных. Конечно, не на каждый чих, но на каждую более-менее абстрактную часть модели.
    2. На каждое частичное представление - свой css-файл.
    3. Каждый элемент взаимодействия с пользователем - свой js-компонент.

    Обычный todo-mvc превращается с таким подходом вот в такую структуру:

    todo/
    todo.view
    todo.css
    todo.js
    todo_test.js
    todoitem/
    todoitem.partial
    todoitem.css
    todoitem.js
    todoitem_test.js

    Каждое представление состоит из маленького куска верстки, редко больше 50 строк. Каждый css- и js-файл - аналогично. Последний проект, который я делал по такой схеме пережил два года, примерно 10000 коммитов верстки, представлял собой мастер оплаты, веб-приложение и три админки к нему, и до сих пор адекватно функционирует и изменяется.
    Ответ написан
    Комментировать
  • Как реализовать модальное окно на ASP.NET MVC4?

    @Quilin
    Full-stack разработчик
    Попробуйте вернуть ContentResult(Url.Action("Index", "Home")) и на success запроса вручную обновить location.href.

    Также настоятельно не рекомендую вам писать на вьюхах урлы страниц руками, для этого в MVC есть UrlHelper. Достаточно написать

    window.location = "@Url.Action("Index", "Home")"
    Ответ написан
    Комментировать
  • Есть ли нормальная он-лайн система для команды разработчиков?

    @Quilin
    Full-stack разработчик
    Я лично в большом восторге от Assebmla. За 19 долларов в месяц - безлимитные репозитории SVN, Git, Mercurial, Википедия, обмен сообщениями, планировщик задач, стена карт, стендап, SSL и прочая.
    Ответ написан
    Комментировать
  • Действительно ли использование селектора по ID - признак абсолютно плохого стиля?

    @Quilin
    Full-stack разработчик
    Я бы все-таки настоятельно не рекомендовал вам использовать селекторы ID именно в CSS по одной простой причине.

    Движки рендеринга Gecko и Webkit при формировании Reflow и Layout соответственно строят индексы по ID ровно таким же способом, как и по имени класса. В качестве побочного явления - вы можете написать примерно то же, что и здесь, и код будет работать именно таким образом. Как по мне, это несколько неочевидное поведение, что стили применяются ко всем элементам с таким идентификатором, а не только к первому.

    Многие разработчики, да и начинающие верстальщики путают концепцию CSS и их селекторов с особенностями языка XML. Надо понимать, что ID в XML - это строгий параметр, по которому строится индекс с BST, который позволяет быстро находить первое совпадение идентификатора (то же происходит и в JS при вызове document.getElementById("test")), но в CSS и при построении лайаута все гораздо менее строго. И следует заметить, что сами разработчики браузеров решили так сделать, основываясь, вероятнее всего, на концепции того, что верстальщикам нередко приходится повторно пользоваться стилями, описанными для селекторов ID.

    Таким образом, с точки зрения быстродействия "#" ничем не отличается от ".", по крайней мере, в современных вебкитах и фаерфоксах. Теперь что касается точки зрения good practice.

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

    В своей практике я всегда использую идентификаторы для тех нод, которые участвуют в JavaScript, и в уникальности роли которых я уверен. Конечно, там тоже иногда приходится менять, но гораздо реже, чем в CSS. Но для визуального отображения я всегда использую классы, чтобы иметь полное право не писать код повторно, если вдруг дизайнер захочет вставить "тот самый единственный на весь сайт хэдер, его точно больше нигде не будет" в другую часть страницы.

    Ну а что касается аргументов про "больше кода", могу предложить таким борцам за лишний десяток знаков перейти на шаблонизаторы; или перенять даже целиком концепцию БЭМ, тогда код совсем в разы уменьшится.
    Ответ написан
    Комментировать
  • Как оптимизировать код?

    @Quilin
    Full-stack разработчик
    Могу ошибаться, но тем не менее, запрос с ToUpper в C# driver mongoDb выглядит не очень оптимальным. Увы, сейчас нет возможности проверить, но скорее всего для более быстрого решения этой задачи придется создать поле-индекс, в котором уже хранить имя и/или фамилию в upper case, для быстрого к ним доступа через регулярку.

    Также многие разработчики на .NET MVC считают, что обращения к базе данных прямо из контроллера, равно как и вывод данных на вьюхе через ViewData - это моветон.

    Я, увы, не могу написать вам сообщение на хабре, из-за вашего режима ридонли, однако же могу предложить вам поупражняться с подобными задачами на моем проекте, который как раз на ASP.NET MVC + mongoDb/MSSQL. Напишите в Skype v_qilin, если вам интересно.
    Ответ написан
    Комментировать
  • Как динамически заменять PartialView на одной странице?

    @Quilin
    Full-stack разработчик
    Можно воспользоваться библиотекой jquery.unobtrusive.ajax, которая идет в коробке с MVC 3+ и с хелпером AjaxHelper. Я бы не советовал это решение для крупных веб-приложений, поскольку он требует от вас горизонтальной структуры зависимостей, что не всегда бывает удобно (и точно неудобно для модульности), но для небольших страниц - в самый раз, почти ничего писать не надо.

    <div id="Container">
        @Html.Partial("Partial2")
    </div>
    @Ajax.ActionLink(
        "Заменить",
        "Replace",
        "Test",
        new { someId = 12 },
        new AjaxOptions{
            UpdateTargetId = "Container",
            InsertionMode = InsertionMode.Replace,
            HttpMethod = "POST"
        })


    public class TestController : Controller
    {
        [HttpPost]
        public ActionResult Replace(int someId)
        {
            return PartialView("Partial2", someId);
        } 
    }
    Ответ написан
    Комментировать
  • Какой это Реалтайм Дебагер для JS

    @Quilin
    Full-stack разработчик
    Очевидно, самописное что-то, там же урл явно проглядывается.
    Ответ написан
    Комментировать
  • Проблема с подчеркиванием javaskript

    @Quilin
    Full-stack разработчик
    $(window).load(function(){
    	$('.fixBlock').liFixar({
    		side: 'top',
    		position: 0,
    		fix: function(el, side){
    			el.addClass("fixed");
    			el.liFixar('update')
    		},
    		unfix: function(el, side){
    			el.removeClass("fixed");
    			el.liFixar('update')
    		}
    	});
    })


    .hr li {
        background: #FFF;
        color: #000;
    }
    .hr .fixed {
        background: none;
        color: #fff;
    }
    .hr .fixed:hover {
        border-bottom: 1px solid #aa5;
    }


    По-хорошему, ваш JS код не должен хранить данных о внешнем виде сайта. Это нарушает основной принцип декомпозиции логики и отображения и в дальнейшем вам аукнется - например, если у вас появится задача сделать "ночную" версию сайта или мобильную.
    Ответ написан
    Комментировать
  • Как проверить, пустой ли массив в Javascript, и, если он пустой, то создать его?

    @Quilin
    Full-stack разработчик
    Можно написать как-то покороче, ИМХО:

    arr = arr || [];

    Это, конечно, попахивает немного, но для сведущих в JS код вполне прозрачный.
    Ответ написан
    1 комментарий