Как связать событие с элементами DOM, созданными с помощью пользовательского тега JsRender?

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

Вот пример кода, который я сейчас использую:

$.views.tags({
    toggleProp: {
        template: '<span class="toggle">{{include tmpl=#content/}}</span>',
        onAfterLink: function () {
            var prop = this.tagCtx.view.data;
            $(this.parentElem).on('click', '.toggle', function () {
                prop.value(!prop.value());
            });
        },
        onDispose: function () {
            $(this.parentElem).off('click', '.toggle');
        }
    }
    // ... other custom tags simply follow the same pattern ...
});

К тому времени, когда мы ударили onAfterLinkЕсть ли надежный способ доступа к визуализированному элементу DOM (или элементам DOM), соответствующему самому пользовательскому тегу? Без риска поразить неправильный элемент по ошибке? Я понимаю, что пользовательский тег может быть текстом без HTML-элемента, но он все равно будет текстовым узлом, верно? (Могу ли я даже связать события с текстовыми узлами?)

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

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

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

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

1 ответ

Решение

Вместо того чтобы использовать this.parentElem, вы можете использовать

this.contents()

который является объектом jQuery, содержащим все непосредственные элементы содержимого в теге.

Вы также можете предоставить аргумент селектора,

this.contents("someselector")

"фильтровать" и включать необязательный логический "глубокий" флаг для обоих "фильтровать" и "находить" - т.е.

this.contents("someselector", true),

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

Вам может не понадобиться удалять обработчики в onDispose. Если тег удаляется только вместе с его содержимым, вы можете полагаться на тот факт, что jQuery будет располагать обработчиками при удалении элементов из DOM.

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

$.views.tags({
    toggleProp: {
        template: '{{include tmpl=#content/}}',
        onAfterLink: function () {
            var prop = this.tagCtx.view.data;
            this.contents().on('click', function () {
                prop.value(!prop.value());
            });
        },
        onDispose: function () {
            this.contents().off('click');
        }
    }
});

Также взгляните на примеры, такие как http://www.jsviews.com/ которых используется вышеуказанный подход.

Другие вопросы по тегам