<commit_before># ns.View

Вид представляет собой элемент интерфейса.
Он однозначно идентифицируется своим ключом, который строится во время инициализации исходя из [параметров вида](#Параметры).
Разный ключ всегда означает разный экземпляр вида.

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

Ключ очень важен для работы `ns.Box`.
`ns.Box` при каждом обновлении высчитывает ключи для видов, которые должен показать, скрывает все виды, у которых ключ не совпадает и показывает те, которые надо.

## Декларация

Определение нового вида происходит через статическую функцию `ns.View.define`
```js
ns.View.define('viewName', viewDeclObject[, baseView])
```

Объект-декларация состоит из следующих свойств.

### ctor

`ctor` - это функция-конструтор. Обратите внимание, что он вызывается самым первым, до инициализации самого вида, т.о. в конструкторе еще не доступеы некоторые свойства.

Полностью готовый экземпляр бросает событие `ns-view-init`.

```
/**
 * @classdesc prj.vMyView
 * @augments ns.View
 */
ns.View.define('my-view', {
    /**
     * @constructs prj.vMyView
     */
    ctor: function() {
        this._state = 'initial';
        this.CONST = 100;
    }
});
```

### `events`

`events` - объект с декларацией подписок на события, как DOM, так и noscript.

Любая подписка имеет вид:
```json
{
    "на что подписаться@когда": "обработчик"
}
```
Обработчиков может быть названием метода из прототипа или функция. Все обработчики вызываются в контексте вида.

События с суффиксом `@show` вешаются во время показа вида (событие `ns-view-show`) и снимаются во время скрытия (событие `ns-view-hide`).
Аналогично, суффикс `@init` означает, что событие будет активировано на `ns-view-htmlinit` и деактивировано на `ns-view-htmldestroy`.

#### DOM-события

DOM-события от события noscript различаются согласно массиву `ns.V.DOM_EVENTS`. Все, что не входит в этот массив, является "космическим" событием noscript.

DOM-события навешиваются через механизм делегирования.

Примеры деклараций:
```js
{
    // событие click на корневой ноде вида
    "click": "onClick",

    // событие click на нодах к классом selector внутри вида
    "click .selector": "onSelectorClick",

    // событие click на нодах к классом selector внутри вида,
    // из-за @init обработчик навешивается на ns-view-htmlinit и снимается при ns-view-htmldestroy
    "click@init .selector": "onInitSelectorClick",

    // обработчик события scroll на window
    "scroll window": 'onScroll'
}
```

Правила для DOM-событий:

 1. Все (кроме `scroll`) события работают через механизм [event delegation](http://www.nczonline.net/blog/2009/06/30/event-delegation-in-javascript/).
 2. По умолчанию все обработчики навешиваются на `ns-view-show` и снимаются на `ns-view-hide`
 2. Событие `scroll` не всплывает, поэтому навешивается напрямую на ноду, указанную в селекторе.
 3. В качестве селектора можно указать `window` или `document`, в этом случае событие будет навешано на соответствующий глобальный объект.

#### "Космические" события noscript

Декларируются как и остальные события
```js
{
    "my-custom-event": "onCustomEvent",
    "my-custom-init@init": "onCustomInit"
}
```

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

"Косимческие" события работают через единую шину `ns.events`
```js
ns.events.trigger('my-custom-event');
```

#### Встроенные события

Список событий:

* `ns-view-hide` - вида сейчас виден на странице и будет скрыт. Нода вида находится в DOM.
* `ns-view-htmldestroy` - вид сейчас виден на странице, но его нода будет заменена на новую. Нода вида находится в DOM.
* `ns-view-htmlinit` - у вида появилась новая нода, при этом не гарантируется, что она находится в DOM.
* `ns-view-async` - у async-view появилась заглушка. Это единственное событие, которое генерируется для заглушки async-view
* `ns-view-show` - view был показан и теперь виден на странице. Нода вида находится в DOM.
* `ns-view-touch` - view виден и был затронут в процессе обновления страницы. Нода вида находится в DOM.

Правила:

1. События генерируются снизу вверх, т.е. сначала их получают дочерние вида, потом родительские.
2. События генерируются пачками, т.е. сначала одно событие у всех view, потом другое событие у всех view.
3. События генерируются в строго определенном порядке, указанном выше

Примеры последовательностей событий:

* инициализация view: ```ns-view-htmlinit -> ns-view-show -> ns-view-touch```
* перерисовка страница, если view валиден: ```ns-view-touch```
* view был скрыт: ```ns-view-hide``` (без ```ns-view-touch```)
* view был показан: ```ns-view-show -> ns-view-touch```
* view был перерисован: ```ns-view-hide -> ns-view-htmldestroy -> ns-view-htmlinit -> ns-view-show -> ns-view-touch``` (```ns-view-hide``` тут вызывается из тех соображений, что могут быть обработчики, которые вешаются на ```ns-view-show/ns-view-hide``` и при обновлении ноды, они должны быть переинициализированы)

### methods

`methods` - объект с методами вида. По сути является прототипом объекта.

```
/**
 * @classdesc prj.vMyView
 * @augments ns.View
 */
ns.View.define('my-view', {
    /** @lends prj.vMyView.prototype */
    methods: {
        BAR: 100
        foo: function(){}
    }
});
```

### models

`models` позволяет указать модели, от которых зависит вид. Зависимость означает, что

 1. параметры вида будут собраны на основе параметров связанных моделей
 2. в шаблонах вида будут доступны данные связанных моделей
 3. некоторые методы вида будут подписаны на события связанных моделей

По умолчанию вид подписывается на следующие стандартные события модели:
 - `ns-model-changed`
 - `ns-model-insert`
 - `ns-model-remove`
 - `ns-model-destroyed`
и не подписывается на событие `ns-model-touched`.

Если обработчики явно не указаны, то в качестве обработчика стандартных событий устанавливается метод `invalidate`.

```js
ns.View.define('super-view', {
  models: ['album', 'photo']
});
```
<commit_msg>Поправил рендеринг списков в документации<commit_after># ns.View

Вид представляет собой элемент интерфейса.
Он однозначно идентифицируется своим ключом, который строится во время инициализации исходя из [параметров вида](#Параметры).
Разный ключ всегда означает разный экземпляр вида.

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

Ключ очень важен для работы `ns.Box`.
`ns.Box` при каждом обновлении высчитывает ключи для видов, которые должен показать, скрывает все виды, у которых ключ не совпадает и показывает те, которые надо.

## Декларация

Определение нового вида происходит через статическую функцию `ns.View.define`
```js
ns.View.define('viewName', viewDeclObject[, baseView])
```

Объект-декларация состоит из следующих свойств.

### ctor

`ctor` - это функция-конструтор. Обратите внимание, что он вызывается самым первым, до инициализации самого вида, т.о. в конструкторе еще не доступеы некоторые свойства.

Полностью готовый экземпляр бросает событие `ns-view-init`.

```
/**
 * @classdesc prj.vMyView
 * @augments ns.View
 */
ns.View.define('my-view', {
    /**
     * @constructs prj.vMyView
     */
    ctor: function() {
        this._state = 'initial';
        this.CONST = 100;
    }
});
```

### `events`

`events` - объект с декларацией подписок на события, как DOM, так и noscript.

Любая подписка имеет вид:
```json
{
    "на что подписаться@когда": "обработчик"
}
```
Обработчиков может быть названием метода из прототипа или функция. Все обработчики вызываются в контексте вида.

События с суффиксом `@show` вешаются во время показа вида (событие `ns-view-show`) и снимаются во время скрытия (событие `ns-view-hide`).
Аналогично, суффикс `@init` означает, что событие будет активировано на `ns-view-htmlinit` и деактивировано на `ns-view-htmldestroy`.

#### DOM-события

DOM-события от события noscript различаются согласно массиву `ns.V.DOM_EVENTS`. Все, что не входит в этот массив, является "космическим" событием noscript.

DOM-события навешиваются через механизм делегирования.

Примеры деклараций:
```js
{
    // событие click на корневой ноде вида
    "click": "onClick",

    // событие click на нодах к классом selector внутри вида
    "click .selector": "onSelectorClick",

    // событие click на нодах к классом selector внутри вида,
    // из-за @init обработчик навешивается на ns-view-htmlinit и снимается при ns-view-htmldestroy
    "click@init .selector": "onInitSelectorClick",

    // обработчик события scroll на window
    "scroll window": 'onScroll'
}
```

Правила для DOM-событий:

 1. Все (кроме `scroll`) события работают через механизм [event delegation](http://www.nczonline.net/blog/2009/06/30/event-delegation-in-javascript/).
 2. По умолчанию все обработчики навешиваются на `ns-view-show` и снимаются на `ns-view-hide`
 2. Событие `scroll` не всплывает, поэтому навешивается напрямую на ноду, указанную в селекторе.
 3. В качестве селектора можно указать `window` или `document`, в этом случае событие будет навешано на соответствующий глобальный объект.

#### "Космические" события noscript

Декларируются как и остальные события
```js
{
    "my-custom-event": "onCustomEvent",
    "my-custom-init@init": "onCustomInit"
}
```

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

"Косимческие" события работают через единую шину `ns.events`
```js
ns.events.trigger('my-custom-event');
```

#### Встроенные события

Список событий:

* `ns-view-hide` - вида сейчас виден на странице и будет скрыт. Нода вида находится в DOM.
* `ns-view-htmldestroy` - вид сейчас виден на странице, но его нода будет заменена на новую. Нода вида находится в DOM.
* `ns-view-htmlinit` - у вида появилась новая нода, при этом не гарантируется, что она находится в DOM.
* `ns-view-async` - у async-view появилась заглушка. Это единственное событие, которое генерируется для заглушки async-view
* `ns-view-show` - view был показан и теперь виден на странице. Нода вида находится в DOM.
* `ns-view-touch` - view виден и был затронут в процессе обновления страницы. Нода вида находится в DOM.

Правила:

1. События генерируются снизу вверх, т.е. сначала их получают дочерние вида, потом родительские.
2. События генерируются пачками, т.е. сначала одно событие у всех view, потом другое событие у всех view.
3. События генерируются в строго определенном порядке, указанном выше

Примеры последовательностей событий:

* инициализация view: ```ns-view-htmlinit -> ns-view-show -> ns-view-touch```
* перерисовка страница, если view валиден: ```ns-view-touch```
* view был скрыт: ```ns-view-hide``` (без ```ns-view-touch```)
* view был показан: ```ns-view-show -> ns-view-touch```
* view был перерисован: ```ns-view-hide -> ns-view-htmldestroy -> ns-view-htmlinit -> ns-view-show -> ns-view-touch``` (```ns-view-hide``` тут вызывается из тех соображений, что могут быть обработчики, которые вешаются на ```ns-view-show/ns-view-hide``` и при обновлении ноды, они должны быть переинициализированы)

### methods

`methods` - объект с методами вида. По сути является прототипом объекта.

```
/**
 * @classdesc prj.vMyView
 * @augments ns.View
 */
ns.View.define('my-view', {
    /** @lends prj.vMyView.prototype */
    methods: {
        BAR: 100
        foo: function(){}
    }
});
```

### models

`models` позволяет указать модели, от которых зависит вид. Зависимость означает, что

 1. параметры вида будут собраны на основе параметров связанных моделей
 2. в шаблонах вида будут доступны данные связанных моделей
 3. некоторые методы вида будут подписаны на события связанных моделей

По умолчанию вид подписывается на следующие стандартные события модели:

 - `ns-model-changed`
 - `ns-model-insert`
 - `ns-model-remove`
 - `ns-model-destroyed`

и не подписывается на событие `ns-model-touched`.

Если обработчики явно не указаны, то в качестве обработчика стандартных событий устанавливается метод `invalidate`.

```js
ns.View.define('super-view', {
  models: ['album', 'photo']
});
```

{'fraction_non_alphanumeric': 0.10794330916282135, 'fraction_numerical': 0.003955174686882004, 'mean_word_length': 4.193410355156183, 'pattern_counts': {'":': 14, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4389233', 'n_tokens_mistral': 4922, 'n_tokens_neox': 5637, 'n_words': 1358}