Статьи

Введение в дартс: создание маркизы

В этом уроке я познакомлю вас с Dart и с чего начать. В ходе статьи мы создадим простое выделение изображений на основе JavaScript, не написав ни одной строки JavaScript — только Dart.

Примечание. Этот учебник был впервые опубликован в марте 2012 года как бесплатное предложение для наших поклонников на Facebook. Поскольку Activetuts + уже закрылся , мы делаем его бесплатным для всех читателей.


Мы будем строить следующую простую область, скриншот которой показан ниже. Нажмите на изображение, чтобы запустить рабочий пример проекта.

Нажмите на изображение, чтобы запустить проект

Давайте начнем строить небольшой шатер. С этого момента мы будем гораздо более практичны, и я найду время, чтобы объяснить новые вещи по пути.

Обо всем по порядку; На самом деле мы можем написать Dart в любом старом текстовом редакторе, но наиболее удобный способ начать работу и немедленно запустить свой проект в браузере (с помощью JavaScript-компиляции) — это установить Dart Editor.

Перейдите по адресу http://www.dartlang.org/docs/getting-started/editor/ , который должен автоматически определить вашу ОС и предоставить вам соответствующую ссылку для загрузки. Это не маленькая загрузка, около 65 МБ на момент написания, так что начните с нее, прежде чем продолжить чтение.

Редактор дротиков довольно скромный. Он построен на Eclipse, и я надеюсь, что в конечном итоге он будет предлагаться в качестве подключаемого модуля Eclipse для тех, кто уже установил Eclipse. Но пока, это отдельная модификация Eclipse, которая делает Dart и ничего больше.

Он предлагает несколько функций, которые обычно предлагаются в рабочих пространствах Eclipse, например, завершение с учетом языка. Однако большое преимущество, которое он приносит, — это довольно простой способ запустить и запустить проект Dart.

После завершения загрузки извлеките ZIP-файл, и у вас будет папка dart . Вы можете разместить это где угодно; Я перенес мой в папку «Приложения».


Давайте откроем приложение Dart Editor . Вы найдете его прямо в той папке с дротиками, которую вы только что распаковали.

После запуска вы увидите страницу «Добро пожаловать», которая служит отправной точкой для некоторых примеров проектов. На них, безусловно, стоит взглянуть, но мы пока пропустим их и сначала немного познакомимся с языком.

Первое, что вы увидите при открытии Dart Editor

Перейдите в меню « Файл» и выберите « Новое приложение …» или щелкните значок в левом верхнем углу на панели инструментов:

Кнопка на панели инструментов «Новое приложение»

В появившемся окне введите имя для проекта (я использую DartMarquee ). Он захочет сохранить проект в папке с именем dart в вашем домашнем каталоге, но вы можете изменить это, нажав кнопку Обзор …. Обратите внимание, что какую бы папку вы ни выбрали, Dart Editor создаст новую папку в выбранной папке, используя имя, которое вы дали для проекта. Внутри этого будет несколько файлов, созданных для вас, также используя название проекта, который вы предоставили.

Также убедитесь, что выбрано «Веб-приложение», а не «Серверное приложение».

Окно «Новое приложение»

Созданный для вас проект по умолчанию — простой пример Hello World. Вы также можете увидеть, что происходит, прежде чем мы начнем строить наш (немного) более сложный проект. Запустите приложение, выбрав « Инструменты»> «Выполнить» из меню, нажав « Command-R» (Mac) или « Control-R» (ПК) , или нажав зеленую кнопку «play» на панели инструментов:

Кнопка «Выполнить»

Вы можете ожидать, что это откроется в вашем браузере по умолчанию, но — сюрприз! — Откроется браузер Google Chromium (не путать с Chrome; у Chromium монохромный значок синего цвета, а не цветной значок Chrome). Chromium имеет встроенную поддержку языка дартс.

хром

Это не тот процесс, о котором я упоминал ранее, когда файлы Dart компилируются в JavaScript; это виртуальная машина Dart, на которой выполняется обычный код Dart, что здорово, но не очень полезно для тех из нас, кто в настоящее время создает приложения JavaScript. Далее мы сделаем проект скомпилированным в JavaScript.


Если вы измените настройки запуска, то мы сможем заставить Dart скомпилировать в JavaScript. Чтобы изменить эти настройки, выберите меню « Инструменты»> «Управление запусками …» , нажмите Command-Shift-M (Mac) или Control-Shift-M (ПК) или нажмите и удерживайте стрелку вниз рядом с кнопкой на панели инструментов «Выполнить», и выберите Управление запусками … во всплывающем меню.

Опция Manage Launches на панели инструментов

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

Новые цели запуска

Выберите Dart Web Launch из меню. В верхнем поле справа дайте ему осмысленное имя, например, DartMarquee JS или что-то другое, чтобы обозначить, что мы собираемся воспроизвести JavaScript в другом браузере.

В разделе « Цель запуска» нажмите « Обзор …» рядом с HTML-файлом:. Откроется окно, в котором представлены все (один) HTML-файлы, присутствующие в вашем проекте. Нажмите на DartMarquee.html и затем нажмите ОК .

В разделе « Браузер» вы можете оставить флажок по умолчанию или снять этот флажок, а затем указать браузер с помощью кнопки « Выбрать …» . Выбор браузера не должен иметь большого значения, хотя я буду использовать некоторые приемы CSS3, чтобы современный браузер был бы идеальным.

Нажмите Применить, а затем Закрыть .

Теперь запустите проект еще раз, но на этот раз обязательно сделайте это, нажав и удерживая кнопку « Выполнить» на панели инструментов , а затем выбрав новую цель запуска. Теперь вы должны получить то же приложение Hello World в браузере по вашему выбору, который будет использовать JavaScript, скомпилированный из Dart. На самом деле, вы увидите новый файл в списке файлов: DartMarquee.dart.js. Это скомпилированный файл JavaScript.

Теперь, когда вы запустили новый запуск один раз, будущие Run s запомнят это решение и запустят версию JavaScript.

Но мы еще не закончили. HTML-файл настроен на включение файла Dart вместе с другим файлом JavaScript, который интерпретирует файлы Dart в браузере (что очень круто, но не лучше для производственных приложений). Нам нужно отредактировать файл HTML, чтобы использовать скомпилированный файл JavaScript, а не файлы Dart.


Ваш новый проект должен открыться с помощью DartMaquee.dart в главной области редактора. Мы скоро доберемся до этого, но давайте настроим нашу HTML-страницу. Дважды щелкните файл DartMarquee.html в списке файлов слева, и он откроется на новой вкладке в редакторе.

Dart Editor действительно знает только язык Dart, что очень плохо. Вы заметите, что файл HTML открывается без какой-либо окраски синтаксиса или информации о языке. Сейчас этого достаточно для наших целей, но вы можете открыть этот файл (и любой другой файл, не относящийся к Dart) в выбранном вами текстовом редакторе. Мы не будем тратить слишком много времени на файлы не из Dart, поэтому я просто отредактирую их в Dart Editor для этого урока.

Разметка тела — это не то, что нам нужно, но сначала давайте обновим эти теги <script> как упоминалось в последнем шаге. Вы можете полностью удалить первый <script> ; это тот, который включает в себя файл Dart напрямую. Удалить эту строку:

1
<script src=»http://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/dart.js»></script>

(Подсказка: номера строк не включены по умолчанию, но это один из немногих вариантов, доступных в разделе « Предпочтения» ).

Скрипт — это среда исполнения в браузере для Dart; одна изящная особенность заключается в том, что вы можете писать Dart, не компилируя его в JavaScript, и в любом случае запускать его в браузерах. Вам просто нужно включить dart.js. Конечно, это создает дополнительные накладные расходы и влияет на производительность. Довольно крутой трюк, хотя.

Теперь давайте изменим оставшийся <script> чтобы загрузить наш скомпилированный файл JavaScript. Изменить это:

1
<script type=»application/dart» src=»DartMarquee.dart»></script>

К этому:

1
<script src=»DartMarquee.dart.js»></script>

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

Теперь измените этот <h2> на <div> и присвойте ему id marquee .

1
<div id=»marquee»></div>

Вы можете оставить <h1> если хотите; иногда приятно иметь идентификацию страницы.

Наконец, нам нужно сделать ссылку на файл CSS (который мы создадим на следующем шаге). В <head> добавьте <link> :

1
<link rel=»stylesheet» href=»DartMarquee.css»>

Приложение не будет работать, потому что мы удалили <h2> который был нацелен код Dart, не говоря уже о том, что нам все еще нужен файл CSS. Давайте сделаем это дальше.


Мы связались с несуществующим CSS-файлом, поэтому давайте обратимся к этому. В области «Файлы» редактора дротиков щелкните правой кнопкой мыши и выберите в меню « Новый файл» (вы также можете найти « Новый файл …» в меню « Файл» ).

В появившемся окне вам может потребоваться убедиться, что проект DartMarquee выбран в средней области. Затем введите DartMarquee.css в качестве имени файла и нажмите « Готово» .

Окно Новый файл

Этот файл будет готов для редактирования в основной области редактора, но, как и в случае с HTML-файлами, CSS-файлы интеллектуально не поддерживаются с помощью синтаксиса Dart Editor. Не стесняйтесь вносить изменения в CSS в предпочитаемом вами текстовом редакторе. Или, поскольку мы действительно не собираемся углубляться в CSS, просто скопируйте и вставьте форму ниже в Dart Editor:

01
02
03
04
05
06
07
08
09
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#marquee {
    width: 600px;
    height: 400px;
    background-color: #111;
}
 
.mainImage {
    height: 300px;
    background-color: #666;
    position: relative;
}
.mainImage img {
    display: block;
    position:absolute;
    left: 0px;
    top: 0px;
    -webkit-transition: opacity 0.6s ease-out;
       -moz-transition: opacity 0.6s ease-out;
        -ms-transition: opacity 0.6s ease-out;
         -o-transition: opacity 0.6s ease-out;
            transition: opacity 0.6s ease-out;
}
.mainImage img.fade_away {
    opacity: 0;
}
 
.thumbContainer {
    height: 100px;
    background-color: #DDD;
}
 
.button {
    width: 100px;
    height: 100px;
    background-color: #eee;
    position: relative;
    float: left;
}
 
.button .border {
    width: 90px;
    height: 90px;
    position: absolute;
    opacity: 0;
    border: 5px solid orange;
    -webkit-transition: opacity 0.3s ease-out;
       -moz-transition: opacity 0.3s ease-out;
        -ms-transition: opacity 0.3s ease-out;
         -o-transition: opacity 0.3s ease-out;
            transition: opacity 0.3s ease-out;
    cursor: pointer;
}
.button:hover .border {
    opacity: .5;
}
.button.selected .border {
    opacity: 1;
}

Опять же, мы здесь не для обсуждения CSS. Я укажу, что я использую переходы CSS3 для наведения кнопок и изменения основного изображения. В противном случае, это должно быть довольно просто.

Запустите проект еще раз или просто перезагрузите браузер; на этом этапе не будет никакого JavaScript для повторной компиляции. Если вы запускаете из Dart Editor, вернитесь к файлу HTML или Dart; Редактор дротиков не знает, что делать, когда вы «запускаете» из файла CSS.

Вы должны увидеть большой темный прямоугольник. Пока не очень, но вы на правильном пути.


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

В пакете загрузки вы найдете папку с именем images . Скопируйте или переместите эту папку из загружаемого архива в папку вашего проекта, чтобы она находилась на том же уровне, что и другие ваши файлы. Вам, вероятно, понадобится использовать Finder / Explorer для этой задачи, поскольку Dart Editor (пока) не поддерживает импорт или перетаскивание существующих файлов. Однако они появятся в вашем списке файлов, как только вы их установите.

Структура проекта до сих пор

Теперь мы можем войти в некоторый код Dart. Это следующее!


Откройте файл DartMarquee.dart в редакторе. Вы увидите три основных блока кода:

Три основных раздела в файле Dart по умолчанию

Третий блок — это main функция, и это обязательная часть вашего проекта Dart. Дарт будет искать эту функцию как точку входа в исполнение. Сравните это с JavaScript, где скрипты просто выполняются сверху вниз. Вы, конечно, можете повторить эту методологию в JavaScript, но ключевое отличие в том, что вам это не нужно, и если вам это нужно, вы должны вызвать main() самостоятельно; в Dart ожидается, что у вас есть main функция, так как она будет вызвана для вас, как только Dart будет готов начать выполнение вашего приложения.

Это не будет для вас чуждым понятием, если вы программируете на C или Java или даже в ActionScript 3 и используете класс Document. Хорошая вещь об этом — то, что есть стандартизированное, ожидаемое место, чтобы начать выполнение вашего кода.


Дарт привносит с собой надлежащие классы, которые вы можете предпочесть системе прототипов классов и классов JavaScript. Взгляните на второй блок кода в DartMarquee.dart . Это основная часть программы, и это класс с двумя объявленными методами. Мы отбросим большую часть этого кода. Мы войдем в синтаксис по ходу дела, но пока что выделили этот класс так, чтобы он выглядел так:

1
2
3
4
5
6
class DartMarquee {
 
    DartMarquee() {
    }
 
}

Это оставляет объявление класса и конструктор . Объявление класса начинается с class , за которым следует имя класса. То, что этот класс называется DartMarquee является чисто функцией шаблона, используемого в процессе создания приложения в DartEditor. Важно знать, что то, что этот файл называется «DartMarquee.dart», не означает, что внутри должно быть имя класса DartMarquee . Мы не собираемся его менять, потому что это имеет смысл, но Dart похож на PHP или Ruby в том смысле, что вы можете поместить столько определений классов, сколько захотите, в один файл, и именование не должно совпадать с именем файла. (как это происходит в ActionScript).

Определение класса содержится в фигурных скобках. Внутри этого у нас есть конструктор. Это функция, которая запускается, когда создается новый объект из этого класса. Обычно каждый помещает код настройки в конструктор. Обратите внимание, что имя конструктора должно совпадать с именем класса, иначе это не конструктор, а обычный метод.

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

Вы заметите, что в main функции объект DartMarquee с этой строкой:

1
new DartMarquee().run();

Это должно выглядеть как объектно-ориентированный JavaScript. Затем .run() вызывает метод run для вновь созданного объекта. Мы только что удалили этот метод, поэтому давайте изменим эту строку на следующую:

1
new DartMarquee();

Что-то, что меня очень радует в Dart, поскольку кто-то из JavaScript, это возможность легко импортировать и использовать другой код в вашем проекте. Первый блок нашего кода по умолчанию использует один оператор импорта:

1
#import(‘dart:html’);

Это импортирует встроенную библиотеку Dart, которая специально предназначена для HTML-страниц и дает нам доступ к функциям манипулирования DOM. Мы будем импортировать другие библиотеки по мере необходимости, включая ту, которую мы напишем сами.

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

Наш файл DartMarquee.dart должен выглядеть примерно так:

01
02
03
04
05
06
07
08
09
10
11
12
#import(‘dart:html’);
 
class DartMarquee {
 
    DartMarquee() {
    }
 
}
 
function main() {
    new DartMarquee();
}

Давайте наконец напишем код. Мы собираемся добавить target свойство в класс DartMarquee , чтобы основной HTML-элемент, на который мы DartMarquee , был удобен внутри класса.

Сразу после объявления класса и перед конструктором добавьте свойство следующим образом:

1
2
3
4
5
6
7
8
class DartMarquee {
 
    Element _target;
 
    DartMarquee() {
    }
 
}

Обратите внимание на синтаксис здесь: вместо var мы используем тип данных, чтобы одновременно объявить переменную и дать ей тип данных одновременно. Этот синтаксис напоминает C и Java. Имя нашего свойства _target , а строка заканчивается _target . Вы обнаружите, что Дарт гораздо меньше прощает пропущенные точки с запятой.

Интересной особенностью системы типа Dart является то, что она не обязательна. Если вы укажете тип, Dart сделает все возможное, чтобы придерживаться правил набора текста. Но мы также можем отказаться от печати, написав это свойство следующим образом:

1
var _target;

Дарт не будет пытаться сохранить ваши типы в безопасности; у вас будет динамически типизированная переменная, как в JavaScript. Что еще более интересно, чем тот факт, что это необязательно, это то, что вы можете смешивать строгую и динамическую типизацию в одном и том же коде.

Лично, строгая типизация — одна из вещей, которая привлекает меня к Дарту, так как полезно иметь такую ​​ответственность. Это будет последний раз, когда я упоминаю о динамическом наборе текста в Dart.

Мы еще не закончили с этим свойством. Это важное свойство, поэтому давайте установим его в конструкторе.

1
2
3
4
5
6
7
8
class DartMarquee {
 
    Element _target;
 
    DartMarquee(this._target) {
    }
 
}

Это может выглядеть немного неожиданно. Это идиома дартс; конструктор настолько часто получает аргументы, а затем просто использует тело конструктора, чтобы сохранить эти значения в свойствах, что Google создал ярлык.

Обычно параметр метода выглядит так, как вы и ожидаете: подойдет любое имя переменной, но не то, что выглядит как свойство другого объекта. Эти параметры являются обычными параметрами, к которым вы привыкли; они доступны по имени в теле метода.

Однако этот новый синтаксис будет применяться и назначать значение, переданное этому параметру, свойству, обозначенному именем параметра. Другими словами, приведенный выше код идентичен этому коду:

1
2
3
DartMarquee(target) {
    this._target = target;
}

Только нам не нужно писать этот шаблон линии.

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


Теперь, когда у нас настроено целевое свойство, нам нужно дать ему значение. Вернувшись в основную функцию, нам нужно выбрать область <div> и передать ее конструктору.

Dart предоставляет метод поиска элементов HTML с помощью выбора CSS, во многом как в jQuery или любой из популярных библиотек JavaScript. Это обеспечивается библиотекой dart:html импортированной вверху файла, которая также предоставляет переменную document верхнего уровня, которая дает нам глобальный доступ к документу HTML.

Обновите основную функцию, чтобы она выглядела так:

1
2
3
void main() {
    new DartMarquee(document.query(‘#marquee’));
}

Это очень просто: если вы использовали jQuery (или другую библиотеку), это должно быть довольно знакомо. Просто вызовите document.query и передайте селектор. Дарт делает все остальное.


Если вы разрабатывали с использованием JavaScript, скорее всего, вы интенсивно использовали console.log для тестирования и проверки своего кода. Dart предоставляет функцию print которая при компиляции в JavaScript превращается в вызов console.log . Давайте попробуем и протестируем наш проект одновременно.

В конструкторе DartMarquee давайте напечатаем свойство _target чтобы убедиться, что оно установлено.

1
2
3
DartMarquee(this._target) {
    print(this._target);
}

И нажмите Run. В вашем браузере откройте консоль, и вы должны увидеть что-то вроде этого:

Результат печати

Обратите внимание, что на момент написания этой статьи в редакторе дротиков была ошибка, которая выдает предупреждение о том, что «печать» не является методом. Это отслеживается Google и, вероятно, будет исправлено в ближайшее время, если не к тому времени, когда вы прочитаете это. Но если вы видите это предупреждение, просто игнорируйте его; это все еще хорошо компилируется. Это пример кровоточащего края, на котором стоит Дартс; когда я начал писать этот урок, предупреждения о печати не было, это случилось только с самой последней сборкой редактора (сборка 5104).


Мы собираемся создать необходимые HTML-элементы программно и поместить их в нашу цель <div> . Дарт предоставляет очень чистый API для такого рода задач.

Во-первых, давайте создадим еще несколько свойств для хранения некоторых элементов. Добавьте их прямо под первым добавленным вами свойством:

1
2
3
4
5
6
7
class DartMarquee {
 
    Element _target;
    DivElement _mainImage;
    DivElement _thumbContainer;
 
    DartMarquee(this._target) {

Заметьте, как мы используем подчеркивание в качестве префикса? Мало того, что это общее соглашение при именовании частных свойств, это на самом деле идиоматический Dart. Префикс подчеркивания делает свойство (или метод, или даже класс) закрытым. В противном случае, это публично.

Также обратите внимание, как мы ввели их как DivElement ? Еще одна приятная особенность Dart (как минимум, для Интернета) заключается в том, что он предоставляет классы для отдельных элементов HTML, в отличие от более общего подхода, обычно используемого в JavaScript. В результате отдельные типы элементов имеют соответствующие свойства, поэтому ими легко манипулировать с помощью Dart. Например, ImageElement имеет свойство src которому можно легко и безопасно обращаться напрямую с помощью Dart для изменения источника изображения.

Теперь давайте создадим эти элементы. В конструкторе :

1
2
3
4
5
6
7
8
DartMarquee(this._target) {
    _mainImage = new Element.tag(‘div’);
    _mainImage.classes = [«mainImage»];
    _thumbContainer = new Element.tag(‘div’);
    _thumbContainer.classes = [«thumbContainer»];
    target.nodes.add(_mainImage);
    target.nodes.add(_thumbContainer);
}

Здесь много чего происходит; давайте разберемся с этим.

Сначала мы создаем новый DivElement. Но обратите внимание, что мы не пишем new DivElement как вы могли бы ожидать (и, поверьте мне, я ожидал этого и продолжал ожидать этого в течение довольно new DivElement времени, пока не обнаружил правильную технику). Хотя DivElement является классом, он не имеет конструктора, к которому вы можете получить доступ. Вместо этого вы используете именованный конструктор класса Element для создания элемента определенного типа.

Именованные конструкторы — это просто разные конструкторы (вроде перегрузки методов, но на самом деле это не так), которые могут предоставить другой интерфейс для конструирования. В этом случае мы можем указать строкой тип элемента. Вы также можете написать new Element.html('<div>...</div>'); выписать HTML в строковом формате. Два довольно разных подхода, поэтому у нас есть два конструктора.

Как только мы получим наш _mainImage DivElement , мы установим его класс. Element предоставляет свойство classes которое позволяет нам получить доступ к различным классам, которые могут применяться. В данном случае это новый элемент, так что свойство является пустым. Мы установили для него одно имя класса, "mainImage" .

Вы можете ожидать, что classes будут Array (или List , на языке Dart), но на самом деле это Set . Set похож на Array в том, что это набор независимых значений, но ключевое отличие состоит в том, что коллекция неупорядочена ; нет никакой гарантии, что порядок содержащихся значений будет чем-то конкретным или даже одинаковым каждый раз. Это немного влияет на то, как мы работаем со свойством classes , но сейчас это простое присваивание тому, что выглядит как Array содержащий одну String .

Следующие две строки повторяются почти дословно, за исключением того, что мы присваиваем свойство _thumbContainer и назначаем другой класс.

Последние две строки добавляют эти новые Element в DOM, в частности, в target div. Как видите, у Element есть свойство nodes , которое, как и следовало ожидать, является List дочерних элементов. Будучи List (или Array ), мы можем просто add (аналогично нажатию JavaScript) Element в него. И в этот момент элементы находятся в DOM.

Продолжайте и запустите проект снова; потому что мы добавили классы к новым <div> и у нас есть готовый файл CSS, вы должны увидеть небольшое изменение на странице:

HTML-страница в ее нынешнем виде

Нам нужен контент, а не только серые рамки, на которые можно посмотреть. Мы будем управлять нашим маленьким выделением с помощью файла JSON, поэтому давайте посмотрим, как мы делаем HTTP-запрос в Dart.

Сначала давайте создадим файл JSON. Это будет довольно просто, и не должно нуждаться в каких-либо объяснениях само по себе. Создайте новый файл в своем проекте Dart (« Файл»> «Новый файл …» ) и назовите его marquee.json . Добавьте следующий контент:

01
02
03
04
05
06
07
08
09
10
{
    «images»:[
        «scottwills_machinery3.jpg»,
        «scottwills_machinery4.jpg»,
        «scottwills_machinery5.jpg»,
        «scottwills_machinery6.jpg»,
        «scottwills_machinery7.jpg»,
        «scottwills_machinery8.jpg»
    ]
}

Сохраните и вернитесь к DartMarquee.dart . Мы добавим код для загрузки этого файла в конструктор после того, как мы создали наши дополнительные элементы.

1
2
3
4
5
XMLHttpRequest request = new XMLHttpRequest();
String url = ‘marquee.json’;
request.open(«GET», url, true);
request.on.load.add(onJSONLoad);
request.send();

И вот как ты это делаешь.

О, хорошо, небольшое объяснение. Сначала мы создаем объект XMLHttpRequest . Это будет обрабатывать загрузку данных (а также обрабатывать отправку данных, если мы будем делать такие вещи). Следующая строка немного излишняя, но я хотел показать другую создаваемую переменную. Обратите внимание, что String типы могут быть созданы с литералом кавычки, как в JavaScript (и почти во всех других языках). В Dart нет разницы между одинарными и двойными кавычками, в отличие от PHP или Ruby.

Далее мы начинаем работать с объектом XMLHttpRequest . Сначала мы открываем соединение, передавая метод ( "GET" ), url мы только что создали, и, наконец, нас интересует асинхронный запрос ( true ). Это означает, что нам нужно добавить прослушиватель событий, чтобы знать, когда загрузка завершится. Это подводит нас к самой интересной линии:

1
request.on.load.add(onJSONLoad);

Это модель событий Дарт. Объекты, которые отправляют события, имеют свойство on которое действует как «центральное событие», куда вы можете пойти, чтобы спланировать свою следующую вечеринку. На объекте on также будут свойства, соответствующие различным событиям, отправляемым данным объектом; в этом случае load является одним из событий. Каждое из этих свойств события на самом деле представляет собой набор слушателей, к которым мы можем add нового слушателя (в данном случае onJSONLoad ; это еще не было написано, если вам интересно).

К этому синтаксису потребовалось немного привыкнуть, но теперь мне это очень нравится. Это безопаснее и чище, чем request.addEventListener('load', onJSONLoad) , вы не согласны?

Последняя строка нашего предыдущего блока кода просто приводит запрос в движение; send его, чтобы получить наши данные.

Чтобы это работало, нам нужна функция onJSONLoad . Давайте начнем делать это дальше.


Теперь мы можем написать новый метод. Этот метод также является прослушивателем событий (для XMLHttpRequest мы настроили на последнем шаге), но независимо от синтаксиса тот же. Найдите место в классе DartMarquee которое следует после закрытия конструктора, но до закрытия класса — оно должно находиться между двумя закрывающими скобками. Добавьте следующее:

1
2
3
void onJSONLoad(Event e) {
    print(«onJSONLoad»);
}

Синтаксис должен быть довольно очевидным. Он следует синтаксису свойства / переменной, поскольку мы заменили ключевое слово function JavaScript на тип данных. Тип данных — это тип значения, возвращаемого функцией. В этом случае void на самом деле является недостатком типа, так как функция ничего не возвращает. И подобно свойствам, вы можете при желании оставить метод нетипизированным и использовать ключевое слово function вместо типа.

Теперь мы можем попробовать приложение. Запустите его снова и проверьте консоль. Вы должны получить сообщение о том, что наша функция запущена, то есть загружен файл JSON.

Успех!

Давайте на минуту остановимся в действии, чтобы поговорить о теории. Не волнуйтесь, вы узнаете что-то важное по пути.

В коде, который мы только что написали для добавления прослушивателя событий, наш прослушиватель событий правильно связан с областью объекта, которому он принадлежит. В JavaScript это должно быть связано с объектом, который отправил событие. То есть, если вы напишите это в JavaScript:

1
2
myElement.addEventListener(‘click’, onClick);
function onClick() { console.log(this);

Затем this относится к myElement , объекту, выполняющему отправку события. Однако в Dart this относится к объекту, к которому принадлежит слушатель. Попробуйте это; измените print на это:

1
2
3
void onJSONLoad(Event e) {
    print(this);
}

И запустите это снова. Вы должны увидеть это:

'this' is '[object Object]'

ОК, это не совсем хорошо докажет. [object Object] может быть чем угодно. Давайте кратко рассмотрим полезный трюк, чтобы ваши классы описывали себя.

Добавьте метод в DartMarquee именем toString . Этот метод должен возвращать String и не принимать аргументов.

1
2
3
String toString() {
    return «DartMarquee»;
}

Запустите его еще раз, и теперь вы получите следующее:

Наш метод toString вызывается неявно

Это должно проиллюстрировать, что « this » относится к объекту DartMarquee . JavaScript не ведет себя без обходных путей. Это означает, что вам не нужно беспокоиться о привязке функций к их области при добавлении прослушивателей событий, таких как метод bind jQuery и другие подобные решения.


Давайте продолжим и проанализируем наш JSON теперь, когда загружен файл JSON. Мы собираемся проанализировать его и вставить эти URL в свойство, поэтому сначала вернемся к вершине класса и добавим свойство _urls :

1
2
3
4
Element _target;
DivElement _mainImage;
DivElement _thumbContainer;
List<String> _urls;

Этот синтаксис будет выглядеть странно, если вы не из Java. Имя переменной _urls , а тип данных — List<String> . Мы могли бы просто написать List _urls , и это сработало бы, но мы также можем воспользоваться тем, что предлагает Dart. Вернувшись к началу, я описал rei & filig; ed дженерики , а часть типа данных <String> является родовой. То есть элементы в List печатаются как String s. Смысл этого шага состоит в том, чтобы ввести этот синтаксис. Скоро увидим.

Если вы запрограммировали ActionScript 3, вы найдете синтаксис, аналогичный Vector s, и фактически Dart List s и AS3 Vector s по сути одно и то же.


Теперь перейдем к разбору. Удалите оператор print из onJSONLoad и добавьте это:

01
02
03
04
05
06
07
08
09
10
11
void onJSONLoad(Event e) {
    XMLHttpRequest request = e.target;
    Map<String, Object> result = JSON.parse(request.responseText);
    print(«JSON: » + result);
    int i = 0;
    _urls = result[‘images’];
    _urls.forEach((url) {
        print(«url $i: $url»);
        i++;
    });
}

Этот код действительно не так уж и плох. Вот как это ломается.

Строка 2: это просто приведение источника события (найденного в e.target ) к XMLHttpRequest чтобы мы могли более безопасно работать со свойствами в нем.

Строка 3: эта становится немного корявой. Перейдите ко второй половине строки. Мы получаем responseText из объекта XMLHttpRequest , который дает нам необработанный текст, найденный в нашем файле. И мы передаем это в метод parse класса JSON . Это все, что нужно для анализа JSON; это по сути встроенный! Теперь, чтобы убедиться, что мы можем работать с данными, нам нужно сохранить их в переменной. Эта переменная является result . Поскольку я защищаю строгую типизацию, у нее также есть тип. Этот тип Map<String, Object> , что может быть немного пугающим.

Map — это то, что мы называем Object в JavaScript; это коллекция, которая хранит свои значения ключом String .

Поскольку Map является коллекцией, ее можно обобщать (см. Последний шаг), но поскольку технически мы можем указать две вещи (ключ и значение), мы предоставляем два типа. Как ни странно, вы не можете использовать ничего, кроме String для типа ключа, поэтому я не уверен, зачем это нужно указывать. Вполне возможно, что Дарт в конечном итоге позволит использовать любой тип в качестве ключа. Но сейчас это ключ String . Поскольку наши данные JSON являются Object в самом внешнем виде, мы указываем Object в качестве типа значения. У нас есть немного гибкости, в зависимости от структуры JSON.

Строка 4: Теперь, когда мы проанализировали наш JSON, давайте просто распечатаем его, чтобы проверить результат.

Строка 5: инициализировать счетчик. Обратите внимание, что Dart поддерживает тип int .

Строка 6: получите свойство images из основного объекта JSON, который должен быть Array / List , и сохраните его в нашем _urls которое мы установили на последнем шаге.

Строка 7: переберите этот List , используя forEach и анонимную функцию. Обратите внимание на синтаксис для анонимных функций: (url) {...} . Если нет возвращаемого типа, мы можем полностью его отключить и просто начать со списка параметров. Сначала это кажется немного странным, но в конечном итоге приводит к меньшему количеству написанного кода, что довольно приятно.

Строка 8: теперь мы можем распечатать URL вместе с его индексом. Здесь мы видим, что Dart имеет интерполяцию String , которая позволяет вам расширять переменные внутри String и избегать выхода из String , чтобы включить значение переменной. Использование знака доллара означает, что то, что следует, на самом деле является переменной, и Дарт должен интерполировать ее. Опять же, это меньше написанного кода и приводит к гораздо более читаемому коду, чем конкатенация строк.

Строка 9: Надеюсь, эта строка кода не нуждается в объяснении.

Запустите приложение и… э-э-э Эта консоль не выглядит красиво.

Большая старая ошибка

Продолжайте читать для исправления.


Исправление, к счастью, довольно простое. Dart структурирован в библиотеки, и оказывается, что возможность JSON не является частью библиотеки HTML. Нам просто нужно добавить следующую строку в самом верху файла:

1
#import(‘dart:json’);

Запустите проект еще раз, и вы должны получить консоль, полную вывода:

Регистрируемые данные JSON

То, что я нахожу странным, — это то, что компилятор JavaScript ловит, но это только предупреждение. Компилятор распознает, что вы используете класс с именем JSON но не знает, где найти этот класс … это кажется важной вещью, которую нужно уловить. Урок здесь, помимо того, где находится библиотека JSON , заключается в проверке панели «Проблемы» в редакторе дротиков. Он был как бы похоронен среди ложных предупреждений, но был там:

Панель «Проблемы» говорит нам, что мы должны были импортировать библиотеку JSON

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


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

Хотя можно вставить определение второго класса в тот же файл, давайте посмотрим, что произойдет, когда мы решим написать внешний класс. В Dart Editor создайте новый файл для нашего проекта и назовите его MarqueeButton.dart . Вам будет представлен следующий шаблон:

1
2
3
class MarqueeButton {
 
}

Опять же, не требуется, чтобы мы называли класс по имени файла, или наоборот, но это имеет смысл, поэтому мы оставим достаточно хорошо в покое и просто начнем заполнять детали.

А пока давайте просто получим этот функционал, предоставив простой конструктор, который печатает сообщение, чтобы мы могли видеть, как оно работает. Добавьте конструктор в класс:

1
2
3
4
5
6
class MarqueeButton {
 
    MarqueeButton(index, image) {
        print(«$index: $image»);
    }
}

Ничего, мы еще не закончили; это простой конструктор, использующий интерполяцию String .

Но чтобы его использовать, нам нужно убедиться, что класс DartMarquee знает о классе MarqueeButton . В верхней части DartMarqee , где есть два оператора #import , добавьте третью строку, чтобы включить наш новый класс:

1
2
3
#import(‘dart:html’);
#import(‘dart:json’);
#source(‘MarqueeButton.dart’);

Вы ожидали другого # #import , не так ли? #source немного проще, чем #import . #import предназначен для библиотек, которые должны быть объявлены как таковые и могут ссылаться на другие файлы. #source просто включает целевой файл. Следует отметить, что файлы #source d сами по себе не могут ссылаться на другие файлы. Даже #import встроенных библиотек приведет к ошибке компилятора. Таким образом, это простой способ собрать несколько файлов в другой скрипт, но для более сложных структур вы можете рассмотреть возможность создания библиотеки.

Теперь, когда мы ссылаемся на наш новый класс, давайте использовать его. Внизу в onJSONLoad мы заменим существующую print на несколько экземпляров:

01
02
03
04
05
06
07
08
09
10
11
void onJSONLoad(Event e) {
    XMLHttpRequest request = e.target;
    Map<String, Object> result = JSON.parse(request.responseText);
    print(«JSON: » + result);
    int i = 0;
    _urls = result[‘images’];
    _urls.forEach((url) {
        MarqueeButton btn = new MarqueeButton(i, «images/thumbs/» + url);
        i++;
    });
}

Если вы запустите проект еще раз, вы получите более или менее то же самое, только теперь это ведение журнала из класса MarqueeButton .


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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class MarqueeButton {
 
    DivElement _target;
    String _image;
    int _index;
    Function _onClick;
 
    MarqueeButton(this._index, this._image) {
        _target = new Element.tag(‘div’);
        _target.classes = [«button»];
        DivElement border = new Element.tag(‘div’);
        border.classes = [«border»];
        _target.nodes.add(border);
 
        _target.style.backgroundImage = ‘url(«‘+_image+'»)’;
 
        _target.on.click.add(onClick);
    }
 
    void onClick(Event e) {
        _target.classes.add(‘selected’);
        _onClick(this);
    }
 
}

Мы начинаем класс с нескольких свойств, все частные и типизированные. Может быть интересно отметить тип Function . Мы вернемся к этому через мгновение, но это показывает, что функции — это полноценные объекты в Dart, и их можно легко передать по ссылке.

Конструктор в основном предназначен для создания элементов HTML для кнопки. Мы начинаем с нуля; единственное, что передается конструктору, это индекс кнопки и URL-адрес изображения. Мы видели это раньше, создавая и добавляя новые элементы. Строка 15 , однако, представляет что-то новое, хотя я думаю, что вы можете понять, что он делает. Element есть свойство style которое позволяет довольно легко устанавливать стили CSS. Свойства, доступные для объекта style следуют за именами стилей CSS, только удаляя дефис и превращая имя в верблюжий регистр. Обратите внимание, что значение может быть String или, в случае числовых значений, это может быть просто число.

Последняя строка конструктора добавляет прослушиватель события click для кнопки, следуя соглашению, которое мы видели с событиями XMLHttpRequest .

Затем у нас есть метод onClick , слушатель этого события click. В целях стиля мы добавим класс _onClick к элементу, а затем _onClick функцию _onClick . Это, вы помните, это свойство, которое мы объявили ранее. Это отправка событий бедного человека, и в результате DartMarquee установит для этого свойства собственную функцию, чтобы MarqueeButton мог вызывать его. Мы вернемся к настройке через мгновение, и мы не написали соответствующий код DartMarquee . Но поскольку функции являются первоклассными гражданами мира дартс, легко передать эту функцию и выполнить ее несколько произвольно.


Мы закончим урок с некоторыми добытчиками и сеттером. Для непосвященных сеттеры и геттеры — это специальные функции, которые просто возвращают значение (геттеры) или получают значение (сеттеры). Они достаточно распространены, и большинство объектно-ориентированных языков предоставляют некоторый метод для создания неявных сеттеров и геттеров, которые являются функциями, которые вызываются так, как если бы они были свойствами.

У Дартта это тоже есть, и он добавляет к нему немного синтаксического сахара. Добавьте это в конец класса (перед закрывающей фигурной скобкой, но после метода onClick ):

1
2
3
4
5
6
7
DivElement get target() => _target;
int get index() => _index;
 
Function get click() => _onClick;
void set click(Function fn) {
    _onClick = fn;
}

Вы можете видеть сахар в трех добытчиках. Каждый следует этому шаблону:

1
Type get name() => expression;

Тип ничего нового; это тип возврата функции. В getключевом слове означает , что это является неявной функцией добытчика. name()это просто название метода. Следующим является =>оператор, который в основном говорит «вернуть значение, которое указано справа от меня». В случае _target, мы просто обращаемся к значению, хранящемуся в _targetсвойстве, и возвращаем его. Другими словами, базовый метод получения, написанный с немного меньшим количеством кода, чем обычно.

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

1
2
3
DivElement get target() {
    return _target;
}

Мы закончили с MarqueeButtonклассом, поэтому вернемся к DartMarqueeклассу и начнем его использовать.


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

1
2
3
4
5
6
_urls.forEach((url) {
    MarqueeButton btn = new MarqueeButton(i, "images/thumbs/" + url);
    _thumbContainer.nodes.add(btn.target);
    btn.click = onThumbClick;
    i++;
});

Другой nodes.add(), на этот раз на _thumbContainerDIV и добавляя targetв MarqueeButtonобъект.

Затем мы устанавливаем clickсвойство для метода, который нам еще предстоит написать, но сделаем это сейчас:

1
2
3
void onThumbClick(MarqueeButton btn) {
    print("onThumbClick");
}

Мы будем работать над этим дальше, но сейчас мы должны иметь возможность запустить приложение, увидеть миниатюры и щелкнуть по ним, чтобы увидеть сообщение журнала.

Работает большой палец

Мы почти там. Мы сделаем так, чтобы этот клик что-то значил на следующих двух шагах.


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

Сначала нам нужно объявить два свойства. В верхней части класса с другими свойствами добавьте следующие строки:

1
2
MarqueeButton _currentButton;
ImageElement _currentImage;

Затем обновите onThumbClick:

01
02
03
04
05
06
07
08
09
10
11
void onThumbClick(MarqueeButton btn) {
    if (_currentButton != null) {
        _currentButton.target.classes.remove('selected');
    }
    _currentButton = btn;
    ImageElement image = new Element.tag('img');
    image.width = 600;
    image.height = 300;
    image.src = "images/" + _urls[btn.index];
    _mainImage.nodes.add(image);
}

Первое, на что нужно обратить внимание, это то, что мы проверяем наличие значения в _currentButton. Если это так, то мы удаляем .selectedкласс. Затем мы устанавливаем _currentButtonсвойство для кнопки, которая была нажата, в следующий раз.

Ничего не стоит, что Dart обрабатывает Booleans немного иначе, чем вы привыкли. Сет Лэдд имеет рецензию на Booleans в Dart , в которой мы объясняем:

Dart имеет истинный логический тип с именем bool, только с двумя значениями: true и false (и, я полагаю, null). Из-за логических правил преобразования Dart все значения, кроме true, преобразуются в false. Булевы выражения Дартса возвращают фактический логический результат, а не последнее найденное значение.

Следовательно, при проверке существования значения в переменной целесообразно записывать, if (variable != null)а не сокращенную запись, поскольку в этом случае if (variable)отчет может передаваться falseдаже через переменную, в которой хранится действительное значение.

Затем мы создаем элемент изображения, устанавливаем его размер, src, а затем добавляем его как дочерний элемент.

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


Давайте работать над этим исчезать. Добавьте выделенный код ниже к onThumbClickметоду. Обратите внимание, что строка 11 — это изменение по сравнению с тем, как было раньше (оно использует insertAdjacentElement), и строки после этого являются новыми.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
void onThumbClick(MarqueeButton e) {
    if (_currentButton != null) {
        _currentButton.target.classes.remove('selected');
        print(_currentButton.target.classes);
    }
    _currentButton = e;
    ImageElement image = new Element.tag('img');
    image.width = 600;
    image.height = 300;
    image.src = "images/" + _urls[e.index];
    _mainImage.insertAdjacentElement('afterBegin', image);
 
    if (_currentImage != null) _currentImage.classes.add('fade_away');
    _currentImage = image;
    image.on.transitionEnd.add((evt) {
        ImageElement img = evt.target;
        img.remove();
    });
}

Изменение в строке 53 представляет другой способ добавления дочерних элементов. Element.nodes.add()Это хорошо для добавления в конце, но если мы хотим вставить в определенном месте, в данном случае в начале, то nodesне дает нам достаточно вариантов. insertAdjacentElementдействительно предоставляет опции, хотя его интерфейс не так чист, как мог бы быть. На самом деле, он взят из Windows Internet Explorer API. Я стараюсь не быть слишком самоуверенным в учебнике, но это странное решение.

В любом случае, это API, который у нас есть, если мы хотим сделать больше, чем просто добавить дочерние элементы. Мы хотим добавить наш новый образ в начало, поэтому мы переходим "afterBegin"к insertAdjacentElement, что и делает именно это. Этот метод задокументирован в MSDN, если вы хотите описание различных допустимых аргументов для этого параметра.

Остальная часть кода связана с переходом CSS3; добавив .fade_awayкласс к старому изображению (после проверки, чтобы убедиться, что он не нулевой), мы устанавливаем его непрозрачность равным 0, вызывая переход. Затем _currentImageустанавливается новое изображение, чтобы установить для следующего перехода.

Наконец, к текущему изображению добавляется еще один прослушиватель событий, чтобы после завершения перехода мы могли выполнить небольшой код. Все, что мы делаем, это получаем цель события и приводим ее как ImageElement (не обязательно, но это то, что я считаю полезным в целом). Затем, вызвав remove()на ImageElement, мы удалим его из DOM. Другими словами, как только он полностью исчезнет, ​​мы можем полностью удалить его, чтобы сохранить чистоту нашего DOM.

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

Запустите приложение, нажмите один большой палец, чтобы загрузить изображение, затем другой большой палец и смотрите его в безмолвном страхе.

Неподвижное изображение исчезновения в действии

Наше приложение Dart теперь довольно функционально, но вы, вероятно, заметили, что оно имеет один незначительный недостаток: изображение не загружается сразу. Это простое исправление.

В Marquee.dart найдите onJSONLoadметод и добавьте выделенную строку кода внизу:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
void onJSONLoad(Event e) {
    XMLHttpRequest request = e.target;
    Map<String, Object> result = JSON.parse(request.responseText);
    print("JSON: " + result);
    int i = 0;
    _urls = result['images'];
    _urls.forEach((url) {
        MarqueeButton btn = new MarqueeButton(i, "images/thumbs/" + url);
        _thumbContainer.nodes.add(btn.target);
        btn.click = onThumbClick;
        if (i == 0) btn.onClick(null);
        i++;
    });
}

Фактически, если мы находимся на первой итерации, возьмем это MarqueeButtonи вызовем его onClickметод. Вы будете помнить это как слушатель события для события click внутри MarqueeButton. Мы просто вызовем его напрямую, чтобы имитировать щелчок по первой кнопке, чтобы запустить настройку стилей и поместить содержимое в нужное место. Так как метод ожидает параметр события, но на самом деле не используется, мы можем предоставить nullвызов метода для удовлетворения компилятора.

Запустите его еще раз, и теперь у вас должно быть выбрано и готово первое изображение в основной области.


Мы только что поцарапали поверхность Dart, но круто то, что если вы знаете JavaScript, вы уже знаете Dart в каком-то смысле. Вы уже знакомы с тем, что вы можете сделать с HTML-страницей, и вообще, как это сделать. Dart for the Web на самом деле не добавляет никаких возможностей или модных фреймворков, это просто другой язык в той же проблемной области. Если вы хотите узнать больше, вы можете сделать хуже, чем просто писать приложения на Dart. Может быть, откопать небольшой / маленький кусочек JavaScript, который вы сделали, и перенести его на Dart.

Если вам нравится искать в Интернете больше ресурсов, Google, безусловно, ваш друг, хотя название «Дарт» может привести к множеству несвязанных хитов, связанных с игрой в дартс, а не с языком. Много раз мне приходилось указывать «язык дартс» в моих поисках или получать немного более конкретную информацию, чем просто «события дартс». Вокруг немало информации.

Во-первых, официальный сайт Dart находится на dartlang.org . Там вы найдете небольшое учебное пособие, посвященное некоторым уникальным языковым функциям, а также изящный виджет Dartboard, который позволяет писать и выполнять код дротика в браузере (вы даже можете использовать виджет на своем собственном сайте).

Если вы думаете, что знаете, что нужно делать, просто не знаете правильного имени метода или класса, документация по API — хорошее место для начала, с api.dartlang.org . Иногда документы немного обнажены или даже ошибочны, но вам, вероятно, следует начать поиски ответа здесь.

Я уже упоминал список рассылки, расположенный по адресу groups.google.com/a/dartlang.org/group/misc/topics . Это очень активно, и у меня было несколько вопросов, ответили в течение нескольких минут там. Инженеры Google также очень вовлечены в этот список.

На сайте Dart также есть довольно хорошая сравнительная таблица JavaScript-to-Dart, расположенная по адресу synonym.dartlang.org , которая берет общие фрагменты кода JavaScript и показывает эквивалентный код Dart рядом с ним.

Отходя от собственных ресурсов Google, есть несколько блогов, ориентированных на Dart, которые продолжают появляться в поиске. Одним из самых плодовитых является «Japh (r)» Криса Строма, по адресу japhr.blogspot.com/search/label/dartlang , который также пишет книгу о дартс .

Dartosphere ( dartosphere.org) объединяет несколько разных блогов о Дартсе и может стать золотым прииском информации.

Сет Лэдд работает в Google, а его блог на blog.sethladd.com недавно был посвящен Дарту.

DartWatch, на dartwatch.com , является еще одним блогом, посвященным Dart, в котором есть много контента, чтобы занять вас.

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

Последний ресурс: если этот урок вызовет некоторый интерес у читателей Tuts +, то, возможно, мы найдем еще несколько уроков для написания, которые углубятся в мир Dart.


В этом уроке мы узнали, как присоединить слушатели событий к объекту, например:

1
2
someElement.on.click.add(myClickListener);
someHTTPRequest.on.load.add(myLoadListener);

Возможно, вы заметили, что мы не использовали эту модель, когда нам нужно было, чтобы MarqueeButtonобъект связывался с DartMarqueeобъектом. Мы обратились к более слушателю событий lo-fi, где мы просто передаем функцию в объект, а затем вызываем эту функцию изнутри объекта. Вы можете спросить себя, почему мы это сделали? Почему мы не использовали onсвойство для отправки события? Где это шоссе привести к ?

Ответ в том, что Дарт не предоставляет этот механизм событий вне своих собственных объектов. Мало того, эта система событий доступна только для объектов в библиотеках HTML. Это похоже на область, где Google может открыться. Конечно, было бы неплохо, чтобы наши собственные классы стали диспетчерами событий, просто расширяя EventDispatcherкласс или подобное, и с небольшим количеством кода получая этот механизм бесплатно.

Можно создать собственную систему, которая имитирует встроенный механизм, но для целей этого урока я пошел по маршруту lo-fi. Там могут быть некоторые будущие уроки дартс, которые идут глубже.


Дарт будущее? Некоторые говорят, что да, некоторые говорят, нет. Я говорю: «Я не знаю». Я, конечно, заинтригован возможностями, и если он сегодня компилируется в пригодный для использования JavaScript, то, возможно, не имеет значения, если Dart не интерпретируется изначально всеми браузерами.

На данный момент, я бы сказал, что если CoffeeScript является чем-то, что завоевывает популярность, то техника Dart-to-JavaScript, безусловно, имеет такую ​​же возможность. Однако, в отличие от CoffeeScript, у вас возникает некоторый накладной JavaScript, который сегодня может не подходить для подавляющего большинства веб-страниц с поддержкой JavaScript. Например, наш проект DartMarquee компилируется в JavaScript размером более 100 КБ. Это немного для такой простой маркизы. Нужно уметь написать это в обычном JavaScript, с помощью jQuery или подобной библиотеки, для значительно меньшего веса. И тонкости, предоставляемые Dart, с классами, набором текста и импортом, не достаточны для того, чтобы это небольшое приложение действительно оправдало размер.

Но для более крупных приложений, таких как Google Docs , 280 Slides или Mockingbird , вы можете легко оправдать накладные расходы. В любом случае, у вас будет сотни КБ JavaScript, поэтому некоторые дополнительные возможности для процесса компиляции в обмен на более структурированный набор классов определенно понравятся некоторым программистам.

Вот и все для этого введения в Дарт. Спасибо за прочтение. Я надеюсь, что это было полезно для вас!