-
Notifications
You must be signed in to change notification settings - Fork 15
Декоратор @watch
Декоратор @watch
декларирует привязку метода или свойства к определенным событиям компонента. Если он применяется к методу, то можно задать список событий (или отслеживаемых свойств) при которых данный метод будет вызываться, а если декоратор применяется к отслеживаемому свойству, то можно указать название метода (или функцию), который будет вызываться при изменении этого свойства.
import iBlock, { component, field, watch } from 'super/i-block/i-block';
export * from 'super/i-block/i-block';
@component()
export default class bExample extends iBlock {
@field()
i?: number;
// Функция будет вызываться каждый раз при изменении параметра i
@watch('i')
logI(value, oldValue) {
console.log(`this.i was changed: ${value} (old value: ${oldValue})`);
}
// Каждые пол секунды увеличиваем значение i
created() {
super.created();
this.async.setInterval(() => this.i++, 500);
}
}
По умолчанию, вызываемый метод будет получать параметры события, т. е. при изменении наблюдаемого свойства будет передано новое и старое значение и т. д. Если декоратор добавлен к свойству и в качестве параметра передана функция, то первым параметром она будет принимать ссылку на сам компонент.
import iBlock, { component, field, watch } from 'super/i-block/i-block';
export * from 'super/i-block/i-block';
@component()
export default class bExample extends iBlock {
// Если указать строку, то это будет названием вызываемого метода
@watch('logI')
@field()
i?: number;
// Или можно задать функцию
@watch((o, value, oldValue) => {
console.log(`this.j was changed: ${value} (old value: ${oldValue})`);
})
@field()
j?: number;
logI(value, oldValue) {
console.log(`this.i was changed: ${value} (old value: ${oldValue})`);
}
created() {
super.created();
this.async.setInterval(() => {
this.i++;
this.j++;
}, 500);
}
}
Помимо изменений свойств декоратор @watch
позволяет привязываться к различными событиям, например,
import iBlock, { component, field, watch } from 'super/i-block/i-block';
export * from 'super/i-block/i-block';
@component()
export default class bExample extends iBlock {
// Метод будет вызываться каждый раз,
// когда компонент будет испускать событие success
@watch(':success')
onSuccess(component, e) {
console.log('Success!', e.status);
}
// Метод будет вызываться по клику на узел компонента:
// символ ? в начале события означает, что событие должно быть добавлено,
// когда компонент получает хук mounted
@watch('?$el:click')
onClick() {
this.emit('success', {status: 200});
}
}
Синтаксис имени события такой: [хук][источник]: событие
. По умолчанию источник событий — это сам компонент, т. е. слушаются события, которые испускаются через emit
. Хук, на котором добавляются обработчики, по умолчанию равен created
(как правило это именно то, что нужно), но если в начале добавить символ:
-
!
— событие будет добавлено наbeforeCreate
; -
?
— событие будет добавлено наmounted
.
В качестве источника можно использоваться любые свойства компонента, например, rootEvent
или parentEvent
(можно использовать путь к свойству через точку foo.bla.baz
). Также допускается использовать глобальные идентификаторы, например, document
или window
.
import iBlock, { component, field, watch } from 'super/i-block/i-block';
export * from 'super/i-block/i-block';
@component()
export default class bExample extends iBlock {
@watch('!document:click')
onClick() {
this.emit('Click!');
}
}
Декоратор @watch
может принимать объект с параметрами наблюдения:
{
// Имя наблюдаемого свойства или событие
field: string;
// Название вызываемого метода или функция
// (только для случаев, когда декоратор добавляется к свойству)
fn?: string | ((ctx: this, value: unknown, oldValue: unknown) => void);
// Если true, то обработчик будет также вызван при первичной инициализации свойства
// (только для наблюдаемых свойств)
immediate?: boolean;
// Если true, то наблюдение будет также идти за внутренней структурой объекта
// (только для наблюдаемых свойств)
deep?: boolean;
// Если false, то функции обработчику не будут передаваться аргументы
provideArgs?: boolean;
// Если true, то событие или изменение свойства будет обработано только один раз
single?: boolean;
// Функция обертка
wrapper?: (ctx: this, fn: Function) => Function;
// Параметры Async
group?: string;
label?: string | symbol;
join: boolean | 'replace';
}
import iBlock, { component, field, watch } from 'super/i-block/i-block';
export * from 'super/i-block/i-block';
@component()
export default class bExample extends iBlock {
// Клик будет обработан только один раз
@watch({field: 'document:click', single: true})
onClick() {
this.emit('Click!');
}
}
Параметр wrapper
удобно использовать для делегирования DOM событий, например,
import iBlock, { component, field, watch } from 'super/i-block/i-block';
export * from 'super/i-block/i-block';
@component()
export default class bExample extends iBlock {
// Делегируем клик по документу элементу button
@watch({
field: 'document:click',
wrapper: (o, fn) => o.dom.delegateElement('button', fn)
})
onClick() {
this.emit('Click!');
}
}