# Main View & Bootstrap

Одним из основополагающих моментов которые позволяют сократить время разработки любого програмного продукта являеться возможность использования стороннего кода в виде уже готовых библиотек и модулей.

И именно эта потребность отличает **RAD.js** от других библиотек и фреймверков, которые пишуться с **0**, основной целью было дать дополнительные возможности для **Backbone.js**, а не ограничивать его в чем-то.

Поэтому в качестве демонстрации возможностей, мы в нашем примере покажем как использовать стороние библиотеки с **RAD.js**, и начнем мы с **Bootstrap**, сначала покажем как ее можно использовать в стандартном подходе, затем как выделить *бутстрап компоненты* в отдельные, полно фукуиональные компоненты с помощью **RAD.js**.

## Bootstrap

Начнем мы с простого добавления **Bootstrap** библиотеки в наш проект:

```bash
npm i bootstrap --save
```
Но так как наш проект собираеться **webpack**, нам прийдеться добавить loaders для загрузки стилей и assets:

```bash
npm i extract-text-webpack-plugin style-loader css-loader url-loader file-loader --save-dev
```

и внести следующие изменения в наш `webpack.config.js`:

```javascript
...
var ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
    ...
    module: {
        loaders: [
            ...
            // for bootstrap loading
            {
                test: /\.css$/,
                loader: "style-loader!css-loader"
            },
            {
                test: /\.png$/,
                loader: "url-loader?limit=100000"
            },
            {
                test: /\.jpg$/,
                loader: "file-loader"
            },
            {
                test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
                loader: 'url?limit=10000&mimetype=application/font-woff'
            },
            {
                test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
                loader: 'url?limit=10000&mimetype=application/octet-stream'
            },
            {
                test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
                loader: 'file'
            },
            {
                test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
                loader: 'url?limit=10000&mimetype=image/svg+xml'
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin("styles.css"),
        ...
    ]
};
```

Но для того чтобы **webpack** знал какие именно стили загружать, для этого необходимо внести изменения в `index.js`:

```javascript
"use strict";
import {publish} from 'RAD.js'
import MainScreen from './source/views/main'

publish('navigation.show', {
    container: '#screen',
    content: MainScreen
});

/* load css styles via webpack */
require('./node_modules/bootstrap/dist/css/bootstrap.min.css');
require('./source/assets/css/styles.css');
```

Исходники с добавленным **Bootstrap** можно скачать по [ссылке](source/bootstrap.zip). А [здесь](source/markup.zip) Вы можете скачать базовую верстку демо приложения, для того чтобы в дальнейшем не оставливаться именно на верстке.

## Main View

Как было описано [в предидущей части](Introduction.md#structure), `Main View` содержит у нас `menu` и одну из нескольких `view`: `dashboard`, `cars`, `details`, пусть по умолчанию будет отображаться `cars`.

> В дальнейшем, в разделе [*routing*](Routing.md) мы увидим как указывать какие именно вью должны отображаться, а пока нам достаточно и данной варианта.

Изменим наш `main/template.ejs` следующим образом:

```ejs
<%
var menu = require('../../components').menu;
var CarsView = require('./cars');
%>
<div class="container">
    <h1>My Favorite Cars</h1>
    <::menu default="<%= 0 %>" array="<%= ['Dashboard', 'Cars'] %>"/>
</div>
<div class="container">
    <::CarsView/>
</div>
``` 

> на самом деле, в передаче параметров через через прямые ссылки (`default="<%= 0 %>"` и `array="<%= ['Dashboard', 'Cars'] %>"`) нет никакой необходимости, вы бы спокойно могли в наном случае записать, к примеру, в следующем виде: `default="0"` и `array="Dashboard;Cars"`. Но в этом случае вам бы пришлось парсить данные значения, а мы пытаемся сделать туториал мение нагруженным кодом и отразить только суть необходимых вам знаний.

В данном шаблоне нет ничего нового, чего бы мы не изучили в *quick start*: здесть у нас есть стандартная разметка с двумя иньектированными `view`.

## Components

Но, наверное, вы заметили пока не существующий путь `../../components` с которого импортируеться `menu`, в чем причина и почему мы выделили `menu` в непонятные пока **components**, а не сделали нормальной `view`.

Причина достаточна проста и заключаеться в следующем:
нам просто не нужна там `view`. По сути, если обратиться к [флоу](Introduction.md#flow) нашего приложения, то не трудно заметить, что меню у нас состоит из двух кнопок которые переключают типы отображения. Но если мы для этой функции воспользуемся `view` то получим огромный овер инжениринг, по той причине что `view` несет достаточно тяжелую функциональность связаную с тем что она наследуеться от `Backbone.View` и добовляет еще дополнительные функции включая lifecycle методы о которых мы поговорим позже. Вторым критериием того что `menu` не должно быть выполнено в качестве `view` являеться его не связанность с данными приложенияю. 

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

То есть нам нужно что-то что имело бы такой же интерфейс как и `view` для dependency injection, но было бы "легче" с функциональной точки зрения. И тут на помощь приходит интерфейс [dependency injection](basics/Injection.md), который позволяет нам использовать не только `view` но и чистые функции в качестве объекта иньекции.

Но вернемся к нашему коду и создадим отдельную директорию для компонентов, в которой добавим `index.js` и подпапку `menu` с уже знакомыми пустыми `index.js` и `template.ejs`.

### template.ejs
 
В нем пока не будет абсолютно ничего нового, поэтому приведем просто листинг:

```ejs
<div class="btn-group" role="group">
    <button type="button" class="btn btn-info active">Dashboard</button>
    <button type="button" class="btn btn-info">Cars</button>
</div>
```
> Скажем по секрету, мы просто перенесли кусок [верски](source/markup.zip) в наш шаблон и все.

### components/main/index.js

Собственно javascript который описывает базовую заготовку по компоненту:

``` javascript
let templateFn = require('./template.ejs');

function menu(data, content) {
    let refs = templateFn(data, content);
}

export default menu;
```

Как не трудно заметить по факту `component` являеться чистой функцией, имеющей на входе всего два параметра:

1. `data` - объект данных, агрегирующий в себе все данные которые вы указывали в качестве атрибутов тега при вызове компонента. Предназначем для получения данных в шаблоне. Фактически полный аналог объекта возвращаемого функцией [`View.getTemplateData`](../API.md#view_get-template-data)
2. `content` - функция рендеринга контента вашего компонента.

Данная функция компонента вызываеться во время рендеринга и может модифицировать ваш шаблон или DOM структуру полученую после рендеринга (`let refs = templateFn(data, content);`), как как вам необходимо.

> Более подробно  о `components` можно почитать в [документации](guide/Components.md)

К логике обработки данных полученных нашим компонентом мы вернемся в следующей части.

### components/index.js 

А пока подготовим корректный экспорт нашей первой компоненты для иньекции в шаблон `main view`: 

```
import menu from './menu'

module.exports.menu = menu;
```
Зачем мы так сделали? Просто напоминаем еще раз *ES6* `import` и `export` -    на самом деле это обертки которые предоставляються **babel**, а в компиляции шаблонов он не участвует, потому что это бы увеличило бы их размер и уменшило бы быстродействие. Поэтому мы оставили возможность экспорта пока через **webpack** импорт.

### build

Теперь если вы собирете свой проект, то увидите на экране следующую картинку:

![first_step](../assets/first_step.png)

*Не сильно много, но с другой стороны мы практически не затратив услий собрали nested view layout, использовали наш первый component. И конечно не стоит забывать что мы добавили Bootstrap для дальнейшей работы.*

**На что обратить внимание:**

* При старте нашей разработки мы экспортировали наши все `view` с помощью *ES6* експорта, но так как нам понадобилось импортировать `Car View` в шаблоне, с помощью механизмов **webpack** нам пришлось изменить способ экспорта, так же как мы уже описывали в [Quick Start](../quickstart/Injection.md)
* о том что именно использовать в каждом конкретном случае: `view` или `component` решать только вам, а судить можно по двум критериям:
	1. отсутствие необходимости в использовании lifecycle методах `view`
	2. отсутствие связи с бизнес данными приложения
* с помощью *dependency injection* и **webpack** `itemplate-loder` вы можете на прямую вставлять куски шаблонов в ваш шаблон.
* *dependency injection* `components` и `view` основан на инъекции чистых функций, поэтому ингда проще пользоваться ими, но выбор только за вами.

## Source

Исходники этой части нашего проекта можно получить по следующей [ссылке](source/2.zip).

## Что дальше?

В [следующей части](menu.md) мы добавим функциональность в наше `menu` и что бы заставить переключать контент в `main view` 