我如何在 .append() 中调用同一对象的方法?

How may I call a method of the same object inside .append()?

generarGrilla() 创建一个包含一些 html 按钮的输出。 每个按钮调用一个存在于同一对象中的方法 guardarReserva()

当我加载页面时 guardarReserva() 在没有点击任何按钮的情况下被调用,因为这行 console.log("whatever "+this.i); 被打印到控制台中。

如果我确实单击了具有侦听器的按钮之一,则没有任何反应。

var reservasAPP = {
    i:0,
    nombre: function () {
        return $('#h09').val();
    },    
    guardarReserva:function(){
        var reservaConfirmada = $('#horario'+this.i).html('--> '+this.nombre());
        console.log("whatever "+this.i);
        return false;
    },
    generarGrilla: function(){
        //it loads from html using jQuery(document).ready();
        for(this.i=1; this.i<13; this.i++){
            var impresionGrilla = $('#grilla').append("<button class=\"btn btn-primary btn-xs\" onclick=\"return "+this.guardarReserva()+"\">Reservar</button>");
        };
    },

}

你试过 reservasAPP.guardarReserva() 而不是 this.guardarReserva() 吗?

您实际上 运行ning guardarReserva() 在您的 .append() 函数中。这就是为什么您在第一次打开浏览器时立即看到 console.log("whatever "+this.i);

我认为您希望该按钮的 onclick 调用 该功能。为此(假设 reservasAPP 在 window 命名空间中)你可以这样做:

var reservasAPP = {
    i:0,
    nombre: function () {
        return $('#h09').val();
    },    
    guardarReserva:function(){
        var reservaConfirmada = $('#horario'+this.i).html('--> '+this.nombre());
        console.log("whatever "+this.i);
        return false;
    },
    generarGrilla: function(){
        //it loads from html using jQuery(document).ready();
        for(this.i=1; this.i<13; this.i++){
            // ---Change is here ------------------------------------------------------------------------|
            //                                                                                           V
            var impresionGrilla = $('#grilla').append("<button class=\"btn btn-primary btn-xs\" onclick=\"return reservasAPP.guardarReserva();\">Reservar</button>");
        };
    },

}

Why I couldn't use "this" and I need to use "reservasAPP"

那么,让我们看看您的一些原始代码(我会稍微修改一下,让它更短一些),看看为什么它不起作用。

发生好事的行在 generarGrilla 内,在调用 .append() 函数的 for 循环内。

var i_g = $('#grilla').append('<button onclick="return ' + this.guardarReserva() + '">Reservar</button>');

现在您的想法是正确的,当该行代码执行时,this 关键字指向 reservasAPP 对象。但是,您所做的并不是将按钮的 onclick 事件设置为 运行 this.guardarReserva() 立即 运行使用 this.guardarReserva() 函数.

让我们看一个半相关的小例子:

var n = function() {
    return 'John';
};

var str = 'Hello, ' + n();

现在,我们的变量 str 的值是多少?那么,我们正在做两件事:

  1. 首先,我们有一个字符串文字Hello,
  2. 然后我们使用 + 运算符将其与函数 n() returns.
  3. 连接起来

注意我们将如何使用 n() return 而不是文字 'n()' (字符串或函数)。这是因为我们实际上是在 调用 n() 函数。

所以,在一天结束时:

// str = 'Hello, John';

那么,让我们回头看看您的原始代码。那里到底发生了什么?那么,您正在选择 id 设置为 grilla 的所有元素(我假设只有其中一个),然后调用 jQuery append() 函数。 .append() 可以接受一个字符串作为它的参数,它会将那个字符串作为 HTML.

插入到 DOM 中

您的字符串连接了三个不同的东西。

  1. '<button onclick="return '
  2. return值this.guardarReserva()
  3. '">Reservar</button>'

您的 guardarReserva 函数在 returns false 末尾,当与字符串连接时,使用其 .toString() 方法,该方法在 this case returns 实际单词 'false'

因此,如果您查看之前的 HTML,您会看到 HTML 代码如下所示:

<div id="grilla">
    <button onclick="return false">Reservar</button>
</div>

这根本不是你想要的。

相反,为了解决这个问题,我让你传入一个长字符串(其中包括你 想要调用的函数名称)。所以,你的 HTML 最终看起来像:

<div id="grilla">
    <button onclick="return reservasAPP.guardarReserva()">Reservar</button>
</div>

好的,这就是该功能立即 运行ning 的原因,也是您的按钮不起作用的原因。所以我们需要将函数作为字符串传递给 HTML 按钮,以便 运行 在单击时知道该函数。

那么,为什么不能传入字符串:

'<button onclick="return this.guardarReserva()">Reservar</button>'

这与浏览器如何评估该按钮中的 this 关键字有关。

其实我们来做个实验

<button onclick="console.log(this);">CLICK ME</button>

单击按钮时会发生什么?你可以自己做这个实验。您会看到它实际上记录了文字按钮。因为在按钮内联 onclickthis 指的是按钮本身!

您可以使用以下代码双重验证:

    <button id="button-1" onclick="console.log(this.id);">CLICK ME</button>

并看到它记录了字符串 "button-1"(也就是按钮的 id)。

所以,如果 this 指的是按钮,我们就不能离开那个上下文来获取我们的 reservasAPP 对象!通过直接引用 reservasAPP 对象(假设它是在您的主 <script></script> 标记中声明的,因此将其放置在可访问的 window 对象中),我们 可以 访问该对象,从而访问其内部属性。


旁注:

我会使用完全不同的方法来附加我们的 onclick 处理程序。

我会使用 jQuery 的 .on() 函数。这是一个如何定义 generarGrilla:

的示例
generarGrilla: function() {
        for (this.i = 1; this.i < 13; this.i++) {
            // Save our `this` object for later
            var self = this;
            var button = $('<button class="btn btn-primary btn-xs">Reservar</button>');
            
            // Set the `onclick` handler for our button (that isn't in the DOM yet)
            button.on('click', function(event) {
                // Use our saved `self` variable, which points to `reservasAPP`
                return self.guardarReserva();
            });

            // `onclick` is set, insert our button into the DOM
            var impresionGrilla = $('#grilla').append(button);
        };
    }

现在,当您 运行 reservasAPP.generarGrilla(); 时,它会插入您的按钮,它们都会有 onclick 个事件处理程序。

您可以阅读 this post 为什么有些人认为在 HTML 属性上使用附加事件处理程序与内联 JS 更好。