Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Урок. Структура АС3-проекта

Данный урок предназначен для новичков. В нем постараюсь дать ответы на часто возникающие вопросы (прямо или косвенно) относительно структуры проекта. Речь изначально пойдет об AS3-проектах, т.к. AS2 устарел. Однако консерваторы, возможно, почерпнут что-то и для себя.

Среда разработки
Начинающие флеш программисты обычно для все и вся используют одну программу - Adobe Flash. Многим это может показаться удобным, привычным и пр. Да, в Adobe стараются развивать свое детище, но практика показывает, что есть более удобные инструменты для написания кода.
Примерами таких редакторов могут быть Flash Builder (от той же Adobe), Flash Develop, Eclipse, Astella и др. Их количество со временем может увеличиваться, но общие принципы наверняка сохраняться в каждом из них.
А что же Adobe Flash? А он может быть очень полезен как редактор графики и средство для хранения различных ресурсов для вашего проекта, так что не выбрасываем, он пригодится.

Не хочу чтобы меня считали предвзятым, но каждый человек имеет свои предпочтения, и я не исключение. Мне удобней всего писать код в FlashDevelop-е. Поэтому основная масса (если не почти все) моих примеров будет основана на работе именно этой программы.
Немного про FlashDevelop
Программа является абсолютно бесплатной, ее можно скачать с . При установке будет автоматически скачана и установлена Flex SDK. Одним из основных недостатков программы является то, что работает она только в ОС Windows. По сути - это большой блокнот, заточенный под написание кода с достаточно большим количеством плюшек.

По умолчанию буду считать, что она у вас уже установлена.

Итак, хорошая практика программирования предполагает разделение кода и ресурсов. И если с кодом все понятно (в проекте должна быть некая папка, в которой хранятся все классы проекта), то с ресурсами не все так однозначно.
Варианты хранения ресурсов:
1) Как есть: файлы png, mp3, flv, шрифты, xml и пр.
В этом случае есть 2 способа работы с такими данными:
a) их загрузка в процессе работы приложения
b) внедрение на этапе компиляции
2) swf
Также есть 2 способа внедрения, они те же, но 2й менее рационален
3) swc
Внедрение в проект происходит на этапе компиляции.
Немного о предпочтениях.
Часто бывает, что нет необходимости загружать сразу все данные (например, уровень игры). В этом случае есть смысл загружать данные в процессе работы приложения. Это может снизить нагрузку на сервер. Если таких данных много и по своей природе они достаточно разнородны и/или типизированы, то есть смысл загружать их в формате swf. Если данные единичные и особенно если они зависят от запроса на сервер, то это будут единичные файлы, которые будут загружаться в процессе. Если такие данные будут использоваться в вашем приложении в любом случае, то нет смысла их грузить отдельно - лучше вставить в проект на этапе компиляции (варианты 1b)
Выбор того или иного варианта в конечном итоге зависит каждой конкретной задачи.
К преимуществам swc/swf файлов относится то, что один раз их скомпилировав, дальнейшую разработку приложения можно вести, вообще их не трогая.

Создадим проект.


Вам предлагается создать несколько вариантов проектов (в т.ч. и на AS2 и пр.) Для нас основными являются "AS3 Project", "AS3 Project with Preloader". Если вы предпочитаете работу с флексовыми компонентами и программируете MXML, выбирайте соответствующие виды проектов. Данный урок рассчитан на новичков, поэтому эти аспекты здесь рассматриваться не будут, как и работа Air-приложений и пр.
Указываем имя проекта, выбираем путь на жестком диске, где он будет храниться. Остальное опционально.
Я выбрал создание АС3-проекта с прелоадером, назвал его ExampleProject.
Структура такого проекта такова:
Есть собственно файл проекта, его название соответствует тому, которое ранее вводилось в поле Name при создании. Его можно безболезненно переименовать при необходимости.
Также имеется 3 папки:
bin (производное от binary, т.е. для двоичных, бинарных данных) - там будет храниться результат компиляции.
lib (производное от library) - библиотека, там хранятся наработки ваши или сторонних разработчиков, как правило в формате swc
src (производное от source) - там будет "жить" ваш код.
Полезно к этому проекту добавить еще несколько папок:
assets - там хранятся все исходные данные, необходимые для вашего приложения (изображения, звуковые файлы и пр.) - все это обычно затем вставляется в fla
docs - документация по проекту
fla - там хранятся ресурсы проекта, на основании которых создаются swc/swf

Посмотрим теперь на содержимое папки src.

Там мы видим 2 файла:
Main.as - документ-класс проекта, т.е. главный класс проекта, куда добавляются другие объекты. Он как фундамент. Не стоит его нагружать кодом.
Preloader.as - предзагрузчик (по коду в ключевых местах в виде комментариев расставлены подсказки). Принцип его работы в том, что он в конечном swf будет находится в 1м кадре, а экземпляр класса Main во 2м. Особенностью среды флеш является то, что пока не будет загружен какой-то объем данных, они не начнут отображаться. Пока прелоадер не загрузит весь проект, инициатива документ-классу не будет передана. Достигается это путем следующего кода (фрагментов):
В прелоадере
Код ActionScript 3
1
2
3
4
5
private function startup():void 
{
    var mainClass:Class = getDefinitionByName("Main") as Class;
    addChild(new mainClass() as DisplayObject);
}
И в документ-классе
Код ActionScript 3
1
2
[Frame(factoryClass="Preloader")]
public class Main extends Sprite 
В 1м случае мы в качестве строки вводим название документ-класса, во втором в специальном теги аналогичным образом класс прелоадера.

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

Теперь немного по интерфейсу FD.

1) Запуск компиляции. Если запустить сейчас - будет скомпилирован пустой проект.
2) Выбор режима компиляции. Для отладки используйте Debug - так можно увидеть и отследить имеющиеся ошибки. Для финальной версии используйте Release.
3) Зеленым цветом выделяется документ-класс.

Теперь немного об основных настройках проекта.


1) Целевая среда/платформа выполнения
2) Версия ФП, под который будет производиться компиляция
3) Конечный файл, в который будет производится компиляция
4) Размер выходного файла (могут изменяться программно и может зависеть от других настроек в других типах проектов)
5) Частота смены кадров по умолчанию (также может изменяться программно)

Теперь можно заняться собственно проектом. Создадим какой-нибудь несложный проект.
ТЗ нашего проекта:на сцене должна присутствовать кнопка и текстовое поле. В текстовом поле должно отображаться количество кликов по кнопке.
Приступим. Начать необходимо непосредственно с объектов сцены. Для этого создадим класс, который будет содержать текстовое поле и кнопку. Если мыслить категориями , то это будет вьюшка. На MVC сейчас останавливаться на будем - это не является нашей целью в данном уроке.
Создавать этот класс будем во Flash CSx (далее IDE), затем скомпилируем его в swc-библиотеку, которую подключим к нашему проекту.
Запускаем IDE, создаем AS3-проект.

Сразу идем в настройки. File>Publish Settings

*В зависимости от версии IDE внешний вид окна настроек может несколько отличаться. Скриншот получен на основе Flash CS5
Сразу отключаем тип HTML и переходим на вкладку настроек Flash.

1) Выбираем версию ФП под которую будем компилировать. В действительности для наших целей этот пункт не важен, т.к. на выходе мы будем получать классы. наследующиеся от стандартных классов, которые изначально (с появления AS3) присутствует во флеше, не зависимо от версии ФП.
2) Должен быть 3й (честно говоря даже в голову не приходило попробовать поставить меньшее значение, но предполагаю, что это вызовет ошибки)
3) Это и есть наша заветная галочка, которая "говорит" IDE компилировать помимо swf (который нам не понадобится) еще и swc.
Сохраним наш проект в созданную папку fla, назовем его commonAssets.fla.
Если у вас CS5.x, то это будет выглядеть примерно так.

Теперь можно приступить к созданию графической составляющей нашего приложения. Для этого создадим кнопку и текстовое поле. С этого момента начинается "магия". Вся соль в том, что изменение графической составляющей не должно влиять на то, что мы пишем в коде, а изменения кода делают с графикой то, что мы захотим. Если вы работаете на пару с художником/аниматором, то создание (знание) четких спецификаций для тех или иных объектов может существенно сократить время разработки приложения. Подробно расписывать работу с IDE не буду, покажу результат и озвучу ключевые моменты. Ознакомиться с проектом можно во вложении.
Общий принцип при таком подходе таков: создаем мувиклип/спрайт нужного содержания и ассоциируем его с классом, таким образом создание экземпляров этого класса будет создавать то, что мы рисовали в IDE в вышеуказанном мувиклипе/спрайте.
Когда работаете над проектом очень важно следить за порядком, таким образом что бы что-то найти в проекте было легко не только вам, но и абсолютно незнакомому разработчику. Для этого разделяйте контент по папкам, давайте осмысленные названия для слоев, папок, объектов.
В нашем объекте 3 элемента: фон, спрайт, который будет выполнять функции кнопки и текстовое поле.
С фоном мы ничего делать не планируем. А вот 2 других объекта нам интересны, поэтому, для того, что бы можно было обращаться к ним по имени, зададим для них InstanceName:
_mcTest - название спрайта
_txTest - название текстового поля
Обратите внимание на префиксы _mc и _tx. 1й обозначает, что мы имеем дело с мувиклипом/спрайтом, 2й - с текстовым полем. Это называется (немного адаптированной под нужды флеш). Такое именование переменных не является обязательным, но может добавить порядка в ваш код и обеспечить удобный автокомплит, следовательно, уменьшить время разработки.
Не забываем "заэмбедить" нужные глифы шрифта.

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

Как видно, имя будущего объекта изначально задал таким, как будет именован будущий класс.
Для того, что бы создать из него все-таки класс, выбираем его в библиотеке (Ctrl + L), кликая по нему правой кнопкой мыши вызываем контекстное меню, выбираем Properties...

Ставим галочку. Если вы ничего не перемудрили, то по умолчанию все встанет на свои места. При этом Class - имя вашего класса (полное), а Base Class - тот класс, от которого вы наследуетесь. Если ваш объект содержит всего один кадр, то там можно прописать "flash.display.Sprite". Теоретически там же можно прописать и свои классы, но этого делать не следует: изменение графики может повлечь изменение функционала базового класса, а графикой должен управлять код, а не наоборот. Остальные пункты нас не интересуют, жмем OK, сохраняем проект, и компилируем его. При этом будет создана swc с интересующим нас классом.
При создании класса может появится такое окно

Игнорируем его, нажимая OK.
Для нашей задачи (если мы не будем что-нибудь менять в графической составляющей приложения) IDE больше не нужен; возвращаемся к FD.
Если посмотреть на содержимое папки fla, то можно увидеть следующее:

В папке появились скомпилированные swf и swc. Если посмотреть подробней, то внутри можно найти наш класс.
Нажимаем по swc-файлу правой кнопкой мыши и в контекстном меню выбираем "Add To Library"

Таким образом у нас появилась возможность использовать созданный в IDE класс.
Надо отметить, что по умолчанию команда "Add To Library" обеспечивает возможность со всеми классами swc, но если какой-то класс не используется в проекте, то в итоговой swf он также будет отсутствовать.

Настало время "нашкодить"
Не смотря на всю простоту задания, я построил проект основываясь на принципах MVC (ссылка выше, и если по этой части будут вопросы, то это повод для отдельной статьи/темы).
Т.к. проект не большой, я не стал разделять классы по разным папкам, поэтому все находится в пределах одного package-а. При бОльшем проекте это не допустимо, т.к. затрудняет навигацию по проекту.
К текущему проекту добавлены следующие классы:
View - "вьюшка", класс, наследник Sprite-а. Содержит в себе всю графику. Предназначен только для отображения. Имеет ряд публичных методов, доступных контроллеру, с помощью которых последний ей управляет.
Model - класс для хранения данных. Никакой логики, только данные. Некоторые в этот класс добавляют возможность слать события в случая изменения к.-л. параметров. Я считаю это не правильным, но это не суть текущей темы.
Controller - мозг приложения. Содержит в себе логику и ничего кроме логики.
EventTypes - Класс для хранения констант, которые используются при отправке событий внутри приложения. Константы можно также хранить в своем событии, особенно если это событие отличается от стандартного Event.

Листинг для тех, кому лень качать проект

Код ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package 
{
    import flash.display.Sprite;
    import flash.events.Event;
 
    /**
     * ...
     * @author TanaTiX
     */
    [Frame(factoryClass="Preloader")]
    public class Main extends Sprite 
    {
 
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
 
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            var view:View = new View();
            var model:Model = new Model();
            var controller:Controller = new Controller(view, model);
            controller.init();
            addChild(view);
        }
 
    }
 
}
Код ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package  
{
    import assets.testApplication.ViewTemplate;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    
    /**
     * ...
     * @author TanaTiX
     */
    public class View extends Sprite 
    {
        private var _template:ViewTemplate;
        
        public function View() 
        {
            
        }
        
        public function init():void 
        {
            _template = new ViewTemplate();
            _template._mcTest.buttonMode = true;
            _template._mcTest.mouseChildren = false;
            addChild(_template);
            _template._mcTest.addEventListener(MouseEvent.CLICK, onClickChange, false, 0, true);
        }
        
        private function onClickChange(e:MouseEvent):void 
        {
            dispatchEvent(new Event(EventTypes.BUTTON_CLICK));
        }
        
        public function updateClicks(value:uint):void {
            _template._txTest.text = value.toString();
        }
    }
 
}
Код ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package  
{
    /**
     * ...
     * @author TanaTiX
     */
    public class Model 
    {
        
        public function Model() 
        {
            
        }
        
        private var _clicks:int;
        
        public function init():void 
        {
            _clicks = 0;
        }
        
        public function get clicks():int 
        {
            return _clicks;
        }
        
        public function set clicks(value:int):void 
        {
            _clicks = value;
        }
        
    }
 
}
Код ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package  
{
    import flash.events.Event;
    /**
     * ...
     * @author TanaTiX
     */
    public class Controller 
    {
        private var _view:View;
        private var _model:Model;
        
        public function Controller(view:View, model:Model) 
        {
            _model = model;
            _view = view;
        }
        
        public function init():void 
        {
            _model.init();
            _view.init();
            _view.addEventListener(EventTypes.BUTTON_CLICK, onChangeClicksCount);
            _view.updateClicks(_model.clicks);
        }
        
        private function onChangeClicksCount(e:Event):void 
        {
            _model.clicks++;
            _view.updateClicks(_model.clicks);
        }
        
    }
 
}
Код ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package  
{
    /**
     * ...
     * @author TanaTiX
     */
    public class EventTypes 
    {
        public static const BUTTON_CLICK:String = "buttonClick";
        
        public function EventTypes() 
        {
            
        }
        
    }
 
}


Таким образом имеем разделение логики, визуальной части (в т.ч. на уровне кода) и данных.
Удачи в проектах.
Обещанные исходники:


Небольшой бонус для тех, кто решил воспользоваться FD-ом.

Список основных хоткеев (можно переназначать; приведу стандартные, которыми чаще всего пользуюсь) и связанных действий:
  • Ctrl + Shift + 1 - практически универсальное сочетание клавиш, т.е. в зависимости от положения курсора предложит сделать то, что требуется:
    курсор на локальной переменнной - предложит вынести переменную в приватное поле класса
    курсор на переменной класса - предложит создать геттеры/сеттеры
    курсор на атрибуте метода - предложит создать переменную класса, которой присваивается текущее значение
    курсор на каком-то наборе символов - предложит создать метод, переменную, константу (в т.ч. в другом классе, если это возможно)
    курсор на пустом месте - предложит сгенерировать метод toString, основываясь на полях класса
    курсор на не импортированном классе - импортирует его
  • F4 - переход к переменной, методу, константе
  • Shift + F4 - возвращение к предыдущему месту работы
  • Ctrl + U - переводит выделенный текст верхний регистр
  • Ctrl + L - переводит выделенный текст в нижний регистр
  • Ctrl + B - предлагает выбрать из списка нужный сниппет (инструмент, с помощью которого буквально одним кликом можно создать, к примеру, цикл)
  • Ctrl + Q - создает/удаляет однострочный комментарий
  • Ctrl + Shift + Q - создает/удаляет многострочный комментарий
  • Ctrl + I - поиск по проекту
  • Ctrl + R - поиск по имени класса (открытые классы в приоритете)
Ответ: Как сделать то же самое, но используя Flash Bulder вместо Flash Developer? Если делать по аналогии, то классы из .fla не импортируются.

Добавлено через 18 минут
Разобрался. После публикации swc зайти в свойства проекта > Путь сборки ActionScript > Добавить swc. Выбираем свой swc. В списке под ним появится строка Тип ссылки: Объединено с кодом.
Вопрос: Урок. Структура АС3-проекта

Данный урок предназначен для новичков. В нем постараюсь дать ответы на часто возникающие вопросы (прямо или косвенно) относительно структуры проекта. Речь изначально пойдет об AS3-проектах, т.к. AS2 устарел. Однако консерваторы, возможно, почерпнут что-то и для себя.

Среда разработки
Начинающие флеш программисты обычно для все и вся используют одну программу - Adobe Flash. Многим это может показаться удобным, привычным и пр. Да, в Adobe стараются развивать свое детище, но практика показывает, что есть более удобные инструменты для написания кода.
Примерами таких редакторов могут быть Flash Builder (от той же Adobe), Flash Develop, Eclipse, Astella и др. Их количество со временем может увеличиваться, но общие принципы наверняка сохраняться в каждом из них.
А что же Adobe Flash? А он может быть очень полезен как редактор графики и средство для хранения различных ресурсов для вашего проекта, так что не выбрасываем, он пригодится.

Не хочу чтобы меня считали предвзятым, но каждый человек имеет свои предпочтения, и я не исключение. Мне удобней всего писать код в FlashDevelop-е. Поэтому основная масса (если не почти все) моих примеров будет основана на работе именно этой программы.
Немного про FlashDevelop
Программа является абсолютно бесплатной, ее можно скачать с . При установке будет автоматически скачана и установлена Flex SDK. Одним из основных недостатков программы является то, что работает она только в ОС Windows. По сути - это большой блокнот, заточенный под написание кода с достаточно большим количеством плюшек.

По умолчанию буду считать, что она у вас уже установлена.

Итак, хорошая практика программирования предполагает разделение кода и ресурсов. И если с кодом все понятно (в проекте должна быть некая папка, в которой хранятся все классы проекта), то с ресурсами не все так однозначно.
Варианты хранения ресурсов:
1) Как есть: файлы png, mp3, flv, шрифты, xml и пр.
В этом случае есть 2 способа работы с такими данными:
a) их загрузка в процессе работы приложения
b) внедрение на этапе компиляции
2) swf
Также есть 2 способа внедрения, они те же, но 2й менее рационален
3) swc
Внедрение в проект происходит на этапе компиляции.
Немного о предпочтениях.
Часто бывает, что нет необходимости загружать сразу все данные (например, уровень игры). В этом случае есть смысл загружать данные в процессе работы приложения. Это может снизить нагрузку на сервер. Если таких данных много и по своей природе они достаточно разнородны и/или типизированы, то есть смысл загружать их в формате swf. Если данные единичные и особенно если они зависят от запроса на сервер, то это будут единичные файлы, которые будут загружаться в процессе. Если такие данные будут использоваться в вашем приложении в любом случае, то нет смысла их грузить отдельно - лучше вставить в проект на этапе компиляции (варианты 1b)
Выбор того или иного варианта в конечном итоге зависит каждой конкретной задачи.
К преимуществам swc/swf файлов относится то, что один раз их скомпилировав, дальнейшую разработку приложения можно вести, вообще их не трогая.

Создадим проект.


Вам предлагается создать несколько вариантов проектов (в т.ч. и на AS2 и пр.) Для нас основными являются "AS3 Project", "AS3 Project with Preloader". Если вы предпочитаете работу с флексовыми компонентами и программируете MXML, выбирайте соответствующие виды проектов. Данный урок рассчитан на новичков, поэтому эти аспекты здесь рассматриваться не будут, как и работа Air-приложений и пр.
Указываем имя проекта, выбираем путь на жестком диске, где он будет храниться. Остальное опционально.
Я выбрал создание АС3-проекта с прелоадером, назвал его ExampleProject.
Структура такого проекта такова:
Есть собственно файл проекта, его название соответствует тому, которое ранее вводилось в поле Name при создании. Его можно безболезненно переименовать при необходимости.
Также имеется 3 папки:
bin (производное от binary, т.е. для двоичных, бинарных данных) - там будет храниться результат компиляции.
lib (производное от library) - библиотека, там хранятся наработки ваши или сторонних разработчиков, как правило в формате swc
src (производное от source) - там будет "жить" ваш код.
Полезно к этому проекту добавить еще несколько папок:
assets - там хранятся все исходные данные, необходимые для вашего приложения (изображения, звуковые файлы и пр.) - все это обычно затем вставляется в fla
docs - документация по проекту
fla - там хранятся ресурсы проекта, на основании которых создаются swc/swf

Посмотрим теперь на содержимое папки src.

Там мы видим 2 файла:
Main.as - документ-класс проекта, т.е. главный класс проекта, куда добавляются другие объекты. Он как фундамент. Не стоит его нагружать кодом.
Preloader.as - предзагрузчик (по коду в ключевых местах в виде комментариев расставлены подсказки). Принцип его работы в том, что он в конечном swf будет находится в 1м кадре, а экземпляр класса Main во 2м. Особенностью среды флеш является то, что пока не будет загружен какой-то объем данных, они не начнут отображаться. Пока прелоадер не загрузит весь проект, инициатива документ-классу не будет передана. Достигается это путем следующего кода (фрагментов):
В прелоадере
ActionScript 3
1
2
3
4
5
private function startup():void 
{
    var mainClass:Class = getDefinitionByName("Main") as Class;
    addChild(new mainClass() as DisplayObject);
}
И в документ-классе
ActionScript 3
1
2
[Frame(factoryClass="Preloader")]
public class Main extends Sprite
В 1м случае мы в качестве строки вводим название документ-класса, во втором в специальном теги аналогичным образом класс прелоадера.

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

Теперь немного по интерфейсу FD.

1) Запуск компиляции. Если запустить сейчас - будет скомпилирован пустой проект.
2) Выбор режима компиляции. Для отладки используйте Debug - так можно увидеть и отследить имеющиеся ошибки. Для финальной версии используйте Release.
3) Зеленым цветом выделяется документ-класс.

Теперь немного об основных настройках проекта.


1) Целевая среда/платформа выполнения
2) Версия ФП, под который будет производиться компиляция
3) Конечный файл, в который будет производится компиляция
4) Размер выходного файла (могут изменяться программно и может зависеть от других настроек в других типах проектов)
5) Частота смены кадров по умолчанию (также может изменяться программно)

Теперь можно заняться собственно проектом. Создадим какой-нибудь несложный проект.
ТЗ нашего проекта:на сцене должна присутствовать кнопка и текстовое поле. В текстовом поле должно отображаться количество кликов по кнопке.
Приступим. Начать необходимо непосредственно с объектов сцены. Для этого создадим класс, который будет содержать текстовое поле и кнопку. Если мыслить категориями , то это будет вьюшка. На MVC сейчас останавливаться на будем - это не является нашей целью в данном уроке.
Создавать этот класс будем во Flash CSx (далее IDE), затем скомпилируем его в swc-библиотеку, которую подключим к нашему проекту.
Запускаем IDE, создаем AS3-проект.

Сразу идем в настройки. File>Publish Settings

*В зависимости от версии IDE внешний вид окна настроек может несколько отличаться. Скриншот получен на основе Flash CS5
Сразу отключаем тип HTML и переходим на вкладку настроек Flash.

1) Выбираем версию ФП под которую будем компилировать. В действительности для наших целей этот пункт не важен, т.к. на выходе мы будем получать классы. наследующиеся от стандартных классов, которые изначально (с появления AS3) присутствует во флеше, не зависимо от версии ФП.
2) Должен быть 3й (честно говоря даже в голову не приходило попробовать поставить меньшее значение, но предполагаю, что это вызовет ошибки)
3) Это и есть наша заветная галочка, которая "говорит" IDE компилировать помимо swf (который нам не понадобится) еще и swc.
Сохраним наш проект в созданную папку fla, назовем его commonAssets.fla.
Если у вас CS5.x, то это будет выглядеть примерно так.

Теперь можно приступить к созданию графической составляющей нашего приложения. Для этого создадим кнопку и текстовое поле. С этого момента начинается "магия". Вся соль в том, что изменение графической составляющей не должно влиять на то, что мы пишем в коде, а изменения кода делают с графикой то, что мы захотим. Если вы работаете на пару с художником/аниматором, то создание (знание) четких спецификаций для тех или иных объектов может существенно сократить время разработки приложения. Подробно расписывать работу с IDE не буду, покажу результат и озвучу ключевые моменты. Ознакомиться с проектом можно во вложении.
Общий принцип при таком подходе таков: создаем мувиклип/спрайт нужного содержания и ассоциируем его с классом, таким образом создание экземпляров этого класса будет создавать то, что мы рисовали в IDE в вышеуказанном мувиклипе/спрайте.
Когда работаете над проектом очень важно следить за порядком, таким образом что бы что-то найти в проекте было легко не только вам, но и абсолютно незнакомому разработчику. Для этого разделяйте контент по папкам, давайте осмысленные названия для слоев, папок, объектов.
В нашем объекте 3 элемента: фон, спрайт, который будет выполнять функции кнопки и текстовое поле.
С фоном мы ничего делать не планируем. А вот 2 других объекта нам интересны, поэтому, для того, что бы можно было обращаться к ним по имени, зададим для них InstanceName:
_mcTest - название спрайта
_txTest - название текстового поля
Обратите внимание на префиксы _mc и _tx. 1й обозначает, что мы имеем дело с мувиклипом/спрайтом, 2й - с текстовым полем. Это называется (немного адаптированной под нужды флеш). Такое именование переменных не является обязательным, но может добавить порядка в ваш код и обеспечить удобный автокомплит, следовательно, уменьшить время разработки.
Не забываем "заэмбедить" нужные глифы шрифта.

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

Как видно, имя будущего объекта изначально задал таким, как будет именован будущий класс.
Для того, что бы создать из него все-таки класс, выбираем его в библиотеке (Ctrl + L), кликая по нему правой кнопкой мыши вызываем контекстное меню, выбираем Properties...

Ставим галочку. Если вы ничего не перемудрили, то по умолчанию все встанет на свои места. При этом Class - имя вашего класса (полное), а Base Class - тот класс, от которого вы наследуетесь. Если ваш объект содержит всего один кадр, то там можно прописать "flash.display.Sprite". Теоретически там же можно прописать и свои классы, но этого делать не следует: изменение графики может повлечь изменение функционала базового класса, а графикой должен управлять код, а не наоборот. Остальные пункты нас не интересуют, жмем OK, сохраняем проект, и компилируем его. При этом будет создана swc с интересующим нас классом.
При создании класса может появится такое окно

Игнорируем его, нажимая OK.
Для нашей задачи (если мы не будем что-нибудь менять в графической составляющей приложения) IDE больше не нужен; возвращаемся к FD.
Если посмотреть на содержимое папки fla, то можно увидеть следующее:

В папке появились скомпилированные swf и swc. Если посмотреть подробней, то внутри можно найти наш класс.
Нажимаем по swc-файлу правой кнопкой мыши и в контекстном меню выбираем "Add To Library"

Таким образом у нас появилась возможность использовать созданный в IDE класс.
Надо отметить, что по умолчанию команда "Add To Library" обеспечивает возможность со всеми классами swc, но если какой-то класс не используется в проекте, то в итоговой swf он также будет отсутствовать.

Настало время "нашкодить"
Не смотря на всю простоту задания, я построил проект основываясь на принципах MVC (ссылка выше, и если по этой части будут вопросы, то это повод для отдельной статьи/темы).
Т.к. проект не большой, я не стал разделять классы по разным папкам, поэтому все находится в пределах одного package-а. При бОльшем проекте это не допустимо, т.к. затрудняет навигацию по проекту.
К текущему проекту добавлены следующие классы:
View - "вьюшка", класс, наследник Sprite-а. Содержит в себе всю графику. Предназначен только для отображения. Имеет ряд публичных методов, доступных контроллеру, с помощью которых последний ей управляет.
Model - класс для хранения данных. Никакой логики, только данные. Некоторые в этот класс добавляют возможность слать события в случая изменения к.-л. параметров. Я считаю это не правильным, но это не суть текущей темы.
Controller - мозг приложения. Содержит в себе логику и ничего кроме логики.
EventTypes - Класс для хранения констант, которые используются при отправке событий внутри приложения. Константы можно также хранить в своем событии, особенно если это событие отличается от стандартного Event.

Листинг для тех, кому лень качать проект

ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package 
{
    import flash.display.Sprite;
    import flash.events.Event;
 
    /**
     * ...
     * @author TanaTiX
     */
    [Frame(factoryClass="Preloader")]
    public class Main extends Sprite 
    {
 
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
 
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            
            var view:View = new View();
            var model:Model = new Model();
            var controller:Controller = new Controller(view, model);
            controller.init();
            addChild(view);
        }
 
    }
 
}
ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package  
{
    import assets.testApplication.ViewTemplate;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    
    /**
     * ...
     * @author TanaTiX
     */
    public class View extends Sprite 
    {
        private var _template:ViewTemplate;
        
        public function View() 
        {
            
        }
        
        public function init():void 
        {
            _template = new ViewTemplate();
            _template._mcTest.buttonMode = true;
            _template._mcTest.mouseChildren = false;
            addChild(_template);
            _template._mcTest.addEventListener(MouseEvent.CLICK, onClickChange, false, 0, true);
        }
        
        private function onClickChange(e:MouseEvent):void 
        {
            dispatchEvent(new Event(EventTypes.BUTTON_CLICK));
        }
        
        public function updateClicks(value:uint):void {
            _template._txTest.text = value.toString();
        }
    }
 
}
ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package  
{
    /**
     * ...
     * @author TanaTiX
     */
    public class Model 
    {
        
        public function Model() 
        {
            
        }
        
        private var _clicks:int;
        
        public function init():void 
        {
            _clicks = 0;
        }
        
        public function get clicks():int 
        {
            return _clicks;
        }
        
        public function set clicks(value:int):void 
        {
            _clicks = value;
        }
        
    }
 
}
ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package  
{
    import flash.events.Event;
    /**
     * ...
     * @author TanaTiX
     */
    public class Controller 
    {
        private var _view:View;
        private var _model:Model;
        
        public function Controller(view:View, model:Model) 
        {
            _model = model;
            _view = view;
        }
        
        public function init():void 
        {
            _model.init();
            _view.init();
            _view.addEventListener(EventTypes.BUTTON_CLICK, onChangeClicksCount);
            _view.updateClicks(_model.clicks);
        }
        
        private function onChangeClicksCount(e:Event):void 
        {
            _model.clicks++;
            _view.updateClicks(_model.clicks);
        }
        
    }
 
}
ActionScript 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package  
{
    /**
     * ...
     * @author TanaTiX
     */
    public class EventTypes 
    {
        public static const BUTTON_CLICK:String = "buttonClick";
        
        public function EventTypes() 
        {
            
        }
        
    }
 
}


Таким образом имеем разделение логики, визуальной части (в т.ч. на уровне кода) и данных.
Удачи в проектах.
Обещанные исходники:


Небольшой бонус для тех, кто решил воспользоваться FD-ом.

Список основных хоткеев (можно переназначать; приведу стандартные, которыми чаще всего пользуюсь) и связанных действий:
  • Ctrl + Shift + 1 - практически универсальное сочетание клавиш, т.е. в зависимости от положения курсора предложит сделать то, что требуется:
    курсор на локальной переменнной - предложит вынести переменную в приватное поле класса
    курсор на переменной класса - предложит создать геттеры/сеттеры
    курсор на атрибуте метода - предложит создать переменную класса, которой присваивается текущее значение
    курсор на каком-то наборе символов - предложит создать метод, переменную, константу (в т.ч. в другом классе, если это возможно)
    курсор на пустом месте - предложит сгенерировать метод toString, основываясь на полях класса
    курсор на не импортированном классе - импортирует его
  • F4 - переход к переменной, методу, константе
  • Shift + F4 - возвращение к предыдущему месту работы
  • Ctrl + U - переводит выделенный текст верхний регистр
  • Ctrl + L - переводит выделенный текст в нижний регистр
  • Ctrl + B - предлагает выбрать из списка нужный сниппет (инструмент, с помощью которого буквально одним кликом можно создать, к примеру, цикл)
  • Ctrl + Q - создает/удаляет однострочный комментарий
  • Ctrl + Shift + Q - создает/удаляет многострочный комментарий
  • Ctrl + I - поиск по проекту
  • Ctrl + R - поиск по имени класса (открытые классы в приоритете)
Ответ: Не понятен процесс появление папки и мувика. Я выделил на сцене все объекты -> F8 -> поставил галочку экспрот в AS3 -> ОК. У меня получилось в библиотеке 2 мувиклипа.
Вопрос: Поиск выдает результаты, но не переходит по ссылкам

Доброго времени суток! У меня вопрос по поиску. Поиск выдает результаты но не переходит по ссылкам...
смотрел в коде
Код HTML5
1
<a href=""><b>название</b></a>
Добавлено через 1 час 39 минут
Все решил проблему)) это были настройки инфоблока
Ответ: akimovmax79, нез, обращайся, сам такой был))
Вопрос: Результат деления не целое число

При делении переменной у=7 на переменную х=25 программа выдает результат с плавающей точкой.
Условие и код ниже.
Проблему решил функцией toFixed(), но меня интересует природа данного явления.

Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<meta charset="windows-1251">
<script>
//В группе 25 студентов. Определенное количество студентов отсутствует. Определить процент отсутствующих, если отсутствует: 3, 4, 5, 6, 7, 8, 9 человек.
 
 
var x,y,p; // где х - количество студентов, у - количество отсутствующих, р - процент отсутствующих
    document.write(' <XMP> ');
    document.write('Кол-во \t Процент \r');
    document.write(' </XMP> ');
    x = 25;
        for (y = 3; y<=9; y++)
        {   p = y/25*100;
            
    document.write(' <XMP> ');
    document.write(y + '\t \t' + p + '\r');
    document.write(' </XMP> ');
        }
 
</script>
Сообщение от Результат Chrome Версия 54.0.2840.99 m (64-bit)
Кол-во Процент
3 12
4 16
5 20
6 24
7 28.000000000000004
8 32
9 36
Сообщение от Результат IE 11.0.9600.17843IS
Кол-во Процент
3 12
4 16
5 20
6 24
7 28.000000000000003
8 32
9 36
Ответ:
Сообщение от Balanaar
Раздел "Типы данных". Смотрим тип double.
Всё равно результат 0.1 +0.2 выдаёт, как ровно 0.3, а не 0.30000000000000004
Visual Basic
1
2
3
4
5
6
7
Private Sub Command1_Click()
Dim a As Double
Dim b As Double
a = 0.1
b = 0.2
MsgBox a + b ' это alert() на VB
End Sub
Вопрос: Сделать downlist с выдачей результат в div

Всем доброго дня, столкнулся с такой проблемой, мне нужно что-бы после того как пользователь выбрал причину поломки ему выдало цену на ремонт и кнопку консультации. Как привязать событие onchange к последнему выбору, дабы выдавало результат в div. Знаний не много, но просто позарез нужно. Прошу извинить если не совсем правильно выразился.

var created = 0;

        function displayAccordingly {

            if (created == 1) {
                removeDrop();
            }

            //Вызов меню
            var mainMenu = document.getElementById('mainMenu');

            //Создания нового меню
            var whereToPut = document.getElementById('myDiv');
            var newDropdown = document.createElement('select');
			var onchange = document.createElement('displayResultat');
            newDropdown.setAttribute('id',"newDropdownMenu");
            whereToPut.appendChild(newDropdown);
        newDropdown.innerHTML= settings[s1.value].options;
        newDropdown.onchange=function(){
        result.innerHTML=settings[s1.value].cost[e.target.value];// это мы устанавливаем цену
        qq=result.parentNode.appendChild(document.createElement("a"));
        qq.href=settings[s1.value].url;

            if (mainMenu.value == "PC") { //Стационар
			
			var optionApple=document.createElement("option");
                optionApple.text="-------";
                newDropdown.add(optionApple,newDropdown.options[null]);

                
                var optionApple=document.createElement("option");
                optionApple.text="Не запускается";
                newDropdown.add(optionApple,newDropdown.options[null]);


                var optionBanana=document.createElement("option");
                optionBanana.text="Глючит Windows";
                newDropdown.add(optionBanana,newDropdown.options[null]);

            } else if (mainMenu.value == "NOTE") { //Ноутбук

                //
                var optionSpinach=document.createElement("option");
                optionSpinach.text="Не запускается";
                newDropdown.add(optionSpinach,newDropdown.options[null]);

                //
                var optionZucchini=document.createElement("option");
                optionZucchini.text="Чистка от пыли";
                newDropdown.add(optionZucchini,newDropdown.options[null]);
				
				} else if (mainMenu.value == "PLAN") { //Планшет
				var optionZucchini=document.createElement("option");
                optionZucchini.text="Прошивка";
                newDropdown.add(optionZucchini,newDropdown.options[null])
				var optionZucchini=document.createElement("option");
                optionZucchini.text="Ремонт";
                newDropdown.add(optionZucchini,newDropdown.options[null])
				
				
				} else if (mainMenu.value == "TEL") { //Телефон
				var optionZucchini=document.createElement("option");

                optionZucchini.text="Ремонт";
                newDropdown.add(optionZucchini,newDropdown.options[null])
				var optionZucchini=document.createElement("option");
                optionZucchini.text="Прошивка";
                newDropdown.add(optionZucchini,newDropdown.options[null])


            }

            created = 1

        }

        function removeDrop() {
            var d = document.getElementById('myDiv');

            var oldmenu = document.getElementById('newDropdownMenu');

            d.removeChild(oldmenu);
        }


<select class='btn btn-primary' id="mainMenu" onchange="displayAccordingly()">
    <option value="">--</option>
    <option value="PC">Компьютер</option>
    <option value="NOTE">Ноутбук</option>
    <option value="PLAN">Планшет</option>
    <option value="TEL">Телефон</option>
</select>
<div id="myDiv"></div>

<!-- Итог -->
<tr>
    <td width="250" class="td_result">ИТОГО:</td>
    <td class="td_result"><div id="result">0</div> руб.</td>
Ответ:
Сообщение от bloodmoneys
Подскажите пожалуйста как это можно
Вообще то правильнее бы не списки с ценами на клиенте среди которых выбор цен происходит, а клиент лишь уточняет услугу во втором списке, цену же (расчет неких цен) должен возвращать сервер.
То есть это связанные списки, а не меню, каждый из которых делает асинхронный запрос на сервер. Результатом запроса первого должен быть второй список, а результатом запроса второго цена.
Вопрос: AJAX отправка файлов на почту

Почему-то не приходят вложения в письмах - сами письма приходят, а вложений нет.

Вот разметка и скрипты

$('#proj_form').submit(function(event) {
        event.preventDefault();
        var formValid = true;
        $('#proj_form input,textarea').each(function() {
          if ($(this).attr('id') == 'text-captcha') { return true; }
          var formGroup = $(this).parents('.form-group');
          var glyphicon = formGroup.find('.form-control-feedback');
          if (this.checkValidity()) {
            formGroup.addClass('has-success').removeClass('has-error');
            glyphicon.addClass('glyphicon-ok').removeClass('glyphicon-remove');
          } else {
         	formGroup.addClass('has-error').removeClass('has-success');
    	    glyphicon.addClass('glyphicon-remove').removeClass('glyphicon-ok');
    	    formValid = false;  
          }
        });
    
    	  var name = $("#proj_name").val();
          var phone = $("#proj_phone").val();
          var time = $("#proj_time").val();
          var message = $("#proj_message").val();
          var captcha = $("#proj-captcha").val();
      var file_data = $('#proj_image').prop('files')[0];  
      var form_data = new FormData();                  
      form_data.append('file', file_data);
      form_data.append('name', name);
      form_data.append('email', email);
      form_data.append('message', message);
      form_data.append('captcha', captcha);
          $.ajax({
            type: "POST",
            url: "feedback/send_proj.php",
    			data: form_data,
    			contentType: false,
    			processData: false,
    			cache: false,
            success : function(text){
              if (text == "success"){
                $('#proj_form').hide();
                $('#msgSubmit_proj').removeClass('hidden');
              }
    	      if (text == "invalidcaptcha") {
    		    inputCaptcha = $("#text-captcha");
                formGroupCaptcha = inputCaptcha.parents('.form-group');
                glyphiconCaptcha = formGroupCaptcha.find('.form-control-feedback');
                formGroupCaptcha.addClass('has-error').removeClass('has-success');
                glyphiconCaptcha.addClass('glyphicon-remove').removeClass('glyphicon-ok');
    			$('#img-captcha').attr('src', 'feedback/captcha.php?id='+Math.random()+'');
    			$("#text-captcha").val('');
    	      }
            }
          }); 
      });


Форма

<form id="proj_form" enctype="multipart/form-data">
      <div class="form-group col-xs-8 col-xs-offset-2">
        <label for="name" class="control-label">Имя*</label>
         <input type="text" class="form-control" id="proj_name" required/>
      </div>
      <div class="form-group col-xs-8 col-xs-offset-2">
        <label for="phone" class="control-label">Телефон*</label>
          <input type="text" class="form-control" id="proj_phone" required/>
      </div>
      <div class="form-group col-xs-8 col-xs-offset-2">
        <label for="time" class="control-label">Время звонка</label>
          <input type="text" class="form-control" id="proj_time"/>
      </div>
      <div class="form-group col-xs-8 col-xs-offset-2">
        <label for="email" class="control-label">Сообщение</label>
          <textarea id="proj_message" class="form-control" rows="3"></textarea>
      </div>
      <div class="form-group col-xs-8 col-xs-offset-2">
        <label for="email" class="control-label">Прикрепите файлы проекта</label>
    		<input type="file" name="image" id="proj_image" value="">
      </div>
      <div class="form-group col-xs-8 col-xs-offset-2">
          <button type="submit" class="btn btn-success send_but">Отправить</button>
      </div>
    </form>


Скрипт обработчика

session_start();
    $name = $_POST["proj_name"];
    $phone = $_POST["proj_phone"];
    $time = $_POST["proj_time"];
    $message = $_POST["proj_message"];
    
      $emailTo = "email@email.ru";
      $subject = "Тема письма";
      $body = "--------------------------------------\n";
      $body .= date("Y.m.d H:i")."\n";
      $body .= "Содержимое заполненных пользователем полей:\n";
      $body .= "Имя: ".$name."\n";
      $body .= "Телефон: ".$phone."\n";
      $body .= "Время звонка: ".$time."\n";
      $body .= "Сообщение: \n".$message."\n";
      $body .= "Сообщение: \n".$file."\n";
    $sourcePath = $_FILES['file']['tmp_name'];
    if ( 0 < $_FILES['file']['error'] ) {
      echo 'Error: ' . $_FILES['file']['error'] . '';
    }
    else {
      move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$_FILES['file']['name']);
    }
      $success = mail($emailTo, $subject, $body, "From: noreply@email.ru \r\n");
      if ($success) {
        echo "success";
      }
      else {
        echo "invalid";
      }
Ответ:
Сообщение от Batyabest
неужели трудно нормально написать без пафоса в голосе?
И где пафос?

Сообщение от Batyabest
спросил почему не отправляется и мне не интересно как правильно оформляются отправления и т.д.
Я ответил почему - не прикрепляются файлы к письму, а как это делается в любом руководстве по РНР рассказано, что мне пересказывать и переписывать это? То что они помещены в форму, не означает автоматом их отправление.

А если не интересно знать, ну так к чему тогда вообще пояснять?
Вопрос: Не загружаются данные через AJAX из PHP-файла после простоя страницы

Привет, коллеги.
У меня проблема с AJAX, после того как загрузил на сервак...

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

Но вот если я открыл страницу, на минут 3-5 забыл про нее и ничего на ней не делал, то функция $.ajax выдает результат, который прописан в error:, т.е. не может подключиться к файлу, который указал в url:
Но сразу после этого я кликаю на кнопку второй раз и она нормально работает. Жму 20-30 раз - все работает без ошибок, выводится нормально.
Жду опять 3 минуты - проблема повторяется.

Есть соображения на этот счет?
Скрин результатов запроса в firebug:

вот кусок кода, обращающегося к файлу. Сначала срабатывает error, потом success при повторном нажатии на кнопку.
CODE (htmlphp):

  1.  
  2. $.ajax({
  3.                 type: "POST",
  4.                 url: 'php/modal_window.php',
  5.                 data: data,
  6.                 beforeSend: function(){
  7.                         $('.wrapper_window').html('').addClass('preloader');
  8.                 },
  9.                 success: function(html){
  10.                         //Вывод данных в окно
  11.                         $('.wrapper_window').removeClass('preloader');
  12.                                
  13.                         $('.wrapper_window').html(html);
  14.                         if(name == 'check_visit')
  15.                         {
  16.                                 open_check_visit();    
  17.                         }
  18.                         if(name == 'sale_ab')
  19.                         {
  20.                                 open_sale_ab();
  21.                         }
  22.                         if(name == 'add_client')
  23.                         {
  24.                                 open_add_client();
  25.                         }
  26.                         if(name == 'card_client')
  27.                         {
  28.                                 open_card_client(id);
  29.                         }
  30.                        
  31.                 },
  32.                 error: function(){
  33.                         float_error("Ошибка вывода данные модального окна!", 1);
  34.                 }
  35.         });
  36.  


В modal_window.php нет ничего тяжелого. Обычный запрос к MySQL базе, вывод данных к модальное окно....

P.S. Что нужно для уточнения, спрашивайте. Первый раз обращаюсь за помощью на форум, не знаю что вам надо скинуть, чтобы лучше вникнуть

(Отредактировано автором: 09 Ноября, 2015 - 23:39:22)

Ответ:
SAD пишет:
короче хз. попробуйте слать с пыха заголовок Connection: close


Кажись нашел. У сервака сессия закрывает после 3-5 минут бездействия, когда проявляю какую-то активность, она восстанавливается и со следующего раза начинает работать.

Пока жду ответа от ТП хостинга, решил сделать костыль. Каждые 30 секунд посылаю пусто ajax запрос, чтобы дать понять серверу, что пользователь активен.

Кажись помогает....
Вопрос: Ajax: Не видит файл-обработчик

Добрый день!
Структура файлов показана на рисунке.
В страницу view_News.php вставляется (include) скрипт comments.php (вывод / ввод комментариев) или comm_ajax.php (ровно то же, но на jquery, оба выделены синим). Обработчики — для каждого — красным
Делал на обычном AJAX:
Javascript
1
2
3
4
5
6
7
8
  xhttp.onreadystatechange=function() {
        if ((this.readyState==4 && this.status==200)) {
      alert(this.responseText);
        }
  }
  xhttp.open('POST','comments_script.php', true); 
  xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  xhttp.send('');
Не видит он файл обработчика comments_script.php

Делал на jQuery
Javascript
1
2
3
4
5
6
7
8
        $.ajax({
          type: 'POST',
          url: 'response.php?action=sample2',
          data: 'name=Andrew&nickname=Aramis',
          success: function(data){
            $('.results').html(data);
          }
        });
То же самое, не видит response.php
Пробовал и пути прописывать по разному: Сайт / Полный путь / и ../Полный путь и просто Полный путь /
И клал в разные папки, вплоть до корневой — результат один и тот же — обработчики comments_script.php и response.php не видятся и ничего не возвращают.
Причем во всех случаях возвращает не что-нибудь, а целая страницу сайта.
Ну то есть код страницы сайта, причем на уровень выше, т.е. для страницы
возвращает стр хотя если бы нашел обработчик, вернул бы просто строку
В чем может быть проблема?
Ответ: Все, разобрался
Поскольку идет переадресация всех запросов на index.php ("одна точка входа"), все url указанные в JS, перекидываются на index. Потому в ответе и выводится весь сайт
1) надо создать папку, для которой это не действует (например repository) и туда складывать обработчики
в .htaccess прописал
RewriteCond %{REQUEST_FILENAME} !^/repository/
RewriteCond %{REQUEST_URI} !^/repository/
2) в скриптах указываю путь типа такого '../repository/comments/comm_script.php' и все работает

Добавлено через 13 минут
Буду признателен, если кто-то укажет на другие варианты решения с .htaccess или без него
Вопрос: Зависимость проектов на Git

Здравствуйте.
Прошу откликнуться знатоков Git
Есть 2 проекта — 1 базовый, другой расширенный.
Первый проект самостоятелен.
Во втором проекте примерно 50% кода первого, почти без изменений.
Остальное — в первом проекте не используется.
Как вести на Git второй проект, чтобы туда автоматом инклюдился, как библиотека, первый проект, со всеми изменениями? Сейчас копирую всё, отслеживая вручную обновленные файлы проекта №1.
Хотелось бы автоматом — какой-нибудь командой обновить репо №2, если репо №1 обновился. Код репо №2 разбросан по папкам и отслеживать это вручную тяжело.
Для примера, что это может быть:
проект №1 — бесплатная версия ЦМС
проект №2 — платная недорогая версия ЦМС
проект №3 — ещё одна разновидность ЦМС для других целей
и т.д.
Ответ:
update-хук + наложение патча во второй репозиторий при изменении первого.
Но правильнее все-таки сабмодули и структурное разделение.
Вопрос: Структура MVC и MVVM

До этого юзал сугубо MVC. Там всё просто и примеров навалом и все в таком виде:
1) Создаются 4 директории: view, model, store и controller
2) Структура файла app.js:
Ext.application({
    name: "XXX",
    appFolder: 'Content/app',

    views: [ ... ],
    models: [ ... ],
    stores: [ ... ],
    controllers: [ ... ],

    viewport: {
        ...
    },

    launch: function () {
        ...
    }
});


А вот с паттерном MVVM ничего понять не могу.
Где хранить: View, ViewController и ViewModel? А то в примерах всё накидано в одну кучу (одну директорию)
Есть ли вообще файл app.js? Если есть, то какова его структура?

Может кто-то подсказать как MVVM реализовано в ExtJS?
Ответ:
Сообщение от potkin
nohuhu,
ЦМД не пользуюсь, но в принципе ясно ...
Зря.

Цитата:
В MVC у View был itemId, по которому в Контроллере задействовались методы. А в MVVM так:
1) Для кнопок нужно объявить toggleHandler: 'onBtnNameClick'
2) Для, например treelist нужен "слушатель" listeners: { itemclick: 'onTreelisttemClick' }
3) И т.д.

Зоопарк одним словом или я что-то не понимаю?
И то, и другое. В старом MVC были только глобальные контроллеры, которые слушали события от *всех* компонентов, и выбирали "свои" события по глобальному селектору. Для того, чтобы не ловить лишние события, селектор нужно было делать максимально избирательным; отсюда рекомендация использовать itemId для идентификации нужных компонентов.

В "новом" MVC есть ViewController, который привязывается к своему view и ловит события только внутри иерархии своего view. Для реакции на события используются методы ViewController, и в конфигурации view вы задаёте названия этих методов.

Что касается toggleHandler и itemclick, то это очень разные вещи. Во-первых, toggleHandler применим только к кнопкам-переключателям; во-вторых, он срабатывает при смене состояния, а не при клике. Вам никто не мешает слушать событие click на кнопках, но обычно для переключателей интересен именно момент смены состояния.

Исторически в Ext для активных компонентов предлагалось два варианта информирования о событиях: собственно событие, на которое можно подписаться (в данном случае toggle), или функция callback, которую можно было указать в конфигурации компонента (toggleHandler). В современном Ext для callback вместо функции можно указать имя метода в ViewController.

Оба варианта функционально идентичны:

Код:
{
    xtype: 'button',
    text: 'foo',
    enableToggle: true,
    toggleHandler: 'onFooToggle'
}, {
    xtype: 'button',
    text: 'bar',
    enableToggle: true,
    listeners: {
        toggle: 'onBarToggle'
    }
}
В TreeList смены состояния нет, поэтому слушайте событие itemclick.