Документация для разработчиков
Темная тема

BX.proxy/BX.delegate

Описание

Function 
BX.proxy(
 Function func,
 Object context
);
Function 
BX.delegate(
 Function func,
 Object context
);

Две родственных функции, генерирующих «функцию-делегата», которая будет вызывать требуемую функцию в нужном контексте. Это может использоваться, например, для назначения метода какого-либо объекта в качестве обработчика события с сохранением контекста объекта.

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

Примечание: BX.delegate - аналог jQuery.proxy.

Примеры использования

Код для получения элемента, по которому был произведен клик:

_hadleMoreButtonClickHandler: function(e)
{
   alert(BX.proxy_context.innerHTML);
}

BX.bind(BX('test'), 'click', BX.delegate(this._hadleMoreButtonClickHandler, this));
<script type="text/javascript">
function MyClass()
{
    this.prop = 1;
    BX.bind(BX('link'), 'click', BX.proxy(this.handler, this));
}

MyClass.prototype.handler = function()
{
    alert(this.prop);
    BX.unbind(BX('link'), 'click', BX.proxy(this.handler, this));
}

BX.ready(function(){ new MyClass(); });
</script>
<a href="javascript:void(0)" id="link">Click Me</a>
function MyClass(){}
MyClass.prototype.handler = function(){}

var ob = new MyClass();
alert(BX.delegate(ob.handler, ob) == BX.delegate(ob.handler, ob)); // false
alert(BX.proxy(ob.handler, ob) == BX.proxy(ob.handler, ob)); // true

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

My.prototype.test = function(d)
{
    console.log(d);
};
My.prototype.send = function()
{
    BX.ajax.get(this._ajaxPage, post, function(data){
        this.test(data);
    });
};

Достаточно стандартная ситуация, когда после ajax-запроса мы совершаем какие-то действия с данными. Однако при исполнении приведенного кода строка this.test(data); приведет к ошибке (т.к. в данном контексте this будет ссылаться на саму анонимную функцию). Для сохранения прозрачности кода достаточно обернуть вызов анонимной функции в BX.delegate:

My.prototype.test = function(d)
{
    console.log(d);
};
My.prototype.send = function()
{
    BX.ajax.get(this._ajaxPage, post, BX.delegate(function(data){
        this.test(data);
    }, this));
};

На этот раз строка this.test(data) выполнится без ошибок и обратится к методу вашего класса My.



Пользовательские комментарии

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

Для этого нужно всего лишь авторизоваться на сайте

Но помните, что Пользовательские комментарии, несмотря на модерацию, не являются официальной документацией. Ответственность за их использование несет сам пользователь.

Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.
0
Леонид Тропин
Если возникнет необходимость передать в функцию обработчик события this.handler некоторые дополнительные параметры, это можно сделать так:
Код
BX.bind(BX('link'), 'click', BX.proxy(function(){this.handler(arg);}, this));

Вот такой вариант работать не будет. Так функция отработает на событии DOMContentLoaded, и обработчик не зарегистрируется:
Код
BX.bind(BX('link'), 'click', BX.proxy(this.handler(arg), this));
****************************************
Комментарий от разработчика: Верно, но лучше сделать так:
Код
this.handler.bind(this, arg)
© «Битрикс», 2001-2021, «1С-Битрикс», 2021
Наверх