Как я могу передать функцию обработчику клика в правильном контексте? - PullRequest
1 голос
/ 24 апреля 2019

Мне нужно получить значение аргумента из функции внутри свойства onlick кнопки, но функция (this.getListItemId(itemId)), которая использует этот аргумент, не находится внутри контекста, из которого находится кнопка.Кнопка находится внутри дочерней функции (this.renderVideoListTemplate()), которая находится внутри родительской функции (getVideoListItems()).Функция, которую я хочу вызвать для события onclick (this.getListItemId()), находится вне того места, где находится функция кнопки (this.renderVideoListTemplate()), поэтому она говорит, что функция (this.getListItemId(itemId)) не существует.

var getVideoListItems = function() {
    var self = this;

    this.renderVideoListTemplate = function(result) {      

        for(let i=0; i < result.length; i++){  
    ====>>> var listItems ="<div class='Button fecharVideo' onclick='"+self.getListItemId(result[i].ID)+"'>"+ 
                                "<span class='Button'>Excluir Vídeo</span>"+
                            "</div>";

            $("#video-list-container").append(listItems);
        };
    };

    this.deleteListItem = function(webUrl, listName, itemId, success, failure) {
        self.getDataByItemId(webUrl,listName,itemId,function(item){
            $.ajax({
                url: item.__metadata.uri,
                type: "POST",
                headers: {
                    "Accept": "application/json;odata=verbose",
                    "X-Http-Method": "DELETE",
                    "If-Match": item.__metadata.etag
                },
                success: function (data) {
                    success();
                },
                error: function (data) {
                    failure(data.responseJSON.error);
                }
            });
        },
       function (error) {
           failure(error);
       });
    };

    this.getListItemId = function(itemId){
        self.deleteListItem(webUrl, listName, itemId)
    };

    return this.init();
}

Ответы [ 3 ]

1 голос
/ 24 апреля 2019

В первую очередь при наблюдении: <a href'#' onclick='this.getListItemId(itemId)'>... этот. будет ссылаться на объект (HTMLElement), который имеет функцию.

Во-вторых: Лучший способ использовать слушатель - это использовать .addEventListener FUNCTION, например: document.querySelector('#id_of_element').addEventListener('click', function(e){ //-- do something with e arg is the event })

Использование element.addEventListener (... отделить код от HTML, сделать его более понятным, простым в управлении и использовании. Кстати, использование именованной функции позволит вам удалитьEventListener, который будет стирать поведение и облегчать работу кода.

1 голос
/ 24 апреля 2019

Я вижу, что вы используете здесь jQuery, вместо простой строки вы можете создать элемент jQuery и добавить прослушиватель с $().on()

Итак, это for loop:

        for(let i=0; i < result.length; i++){  
    ====>>> var listItems ="<div class='Button fecharVideo' onclick='"+self.getListItemId(result[i].ID)+"'>"+ 
                                "<span class='Button'>Excluir Vídeo</span>"+
                            "</div>";

            $("#video-list-container").append(listItems);
        };

может быть преобразовано в следующее:

        for(let i=0; i < result.length; i++){  
            var listItems = $("<div class='Button fecharVideo'><span class='Button'>Excluir Vídeo</span></div>");
            listItems.on('click', function (){
                self.getListItemId(result[i].ID);
            });

            $("#video-list-container").append(listItems);
        };
1 голос
/ 24 апреля 2019

Нельзя назначить ссылку на функцию в строковом значении атрибута onclick.

Вы можете избежать этой проблемы и улучшить логику, используя вместо этого делегированный обработчик событий. Вы можете сохранить result[i].ID в атрибуте data для созданного вами div, который можно прочитать, когда произойдет событие щелчка. Попробуйте это:

// in your object:
this.renderVideoListTemplate = function(result) {
  var divs = result.map(function() {
    return `<div class="Button fecharVideo" data-id="${this.ID}"><span class="Button">Excluir Vídeo</span></div>`
  });
  $("#video-list-container").append(divs);
};

// somewhere else in your codebase:
$('#video-list-container').on('click', '.fecharVideo', function(e) {
  e.preventDefault();
  yourObjectReferece.getListItemId($(this).data('id'));
})

Также обратите внимание на использование map() для построения массива строк для однократного добавления к элементу #video-list-container вместо каждой итерации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...