【问题标题】:Codeigniter 3 application: update MySQL table column and the corresponding view through AjaxCodeigniter 3应用:通过Ajax更新MySQL表列和对应视图
【发布时间】:2018-01-16 22:26:57
【问题描述】:

我正在使用 CodeIgniter 3 和 Twitter Bootstrap 开发一个注册和登录应用程序。

我有一个“users” MySQL 表和一个相应的“users.php”视图,它以 HTML 格式呈现“users”表,如下图所示:

引导表中的“操作”列的每一行都有一个“启用”或“禁用”按钮,具体取决于用户的状态。这部分视图的代码是:

// Status column
<td>
   <?php if ($user->active == 1) {
    echo '<span class="text-success">' . 'Enabled' . '</span>';
    } else {
    echo '<span class="text-danger">' . 'Disabled' . '</span>';
    }
   ?>
</td>

// Enable/Disable buttons
<?php if ($user->active == 1) { ?>
    <a href="<?php echo base_url(); ?>users/deactivate/<?php echo $user->id ?>" title="Deactivate" class="btn btn-success btn-xs state-change" data-role="deactivate" data-id="<?php echo $user->id ?>"><span class="glyphicon glyphicon-ban-circle"></span> Disable</a>
<?php } else { ?>
   <a href="<?php echo base_url(); ?>users/activate/<?php echo $user->id ?>" title="Activate" class="btn btn-success btn-xs state-change" data-role="activate" data-id="<?php echo $user->id ?>"><span class="glyphicon glyphicon-ok"></span> Enable</a>
<?php } ?>

我通过 AJAX 在不刷新页面的情况下激活/停用用户:

$('.state-change').on('click', function(evt) {
    evt.preventDefault();
    var id = $(this).data('id');
    var role = $(this).data('role');
    if (role == "activate") {
        var stateUrl = 'users/activate/';
    } else {
        var stateUrl = 'users/deactivate/';
    }
    $.ajax({
        url: stateUrl + id,
        method: 'GET',
        dataType: 'php',
        success: function(){
            console.log(id);
            console.log(role);
        }
    });
});

问题是有关用户状态的数据没有返回到视图中,并且“状态”和“操作”列没有正确呈现。

我希望我不必使用 jQuery 的 html() 方法或类似方法从成功回调中“静态地”更新视图。

function(){
    console.log(id);
    console.log(role);
    //change columns html here
}

我应该怎么做才能“动态”更新视图?

【问题讨论】:

  • 为什么你不必在成功回调中使用 html 或类似的东西? Ajax 只是做一件事来发送和接收数据,而不是重新加载页面......您可以让用户活动的服务器端脚本触发的唯一方法是重新加载页面。话虽如此,您可以重新加载 div 或特定元素,但在我看来,这首先否定了使用 Ajax 的功效,因为您将整个页面作为响应,而 jquery 只是挑选更新的 div。为此,堆栈上有大量资源,只需搜索 jquery Ajax reload div。
  • 仅供参考,我有一个类似的系统并执行以下操作:pastebin.com/n8JXsLsf
  • 您很可能需要一个相对 URL,例如:/'users/activate 在您的 ajax 成功函数中,您不会从控制器 /'users/activate 获得任何“反馈”。如果您可以将控制器添加到帖子中,那就太好了...
  • 在此处发布图片时,您应该将其他人的电子邮件地址空白。

标签: php jquery mysql ajax codeigniter


【解决方案1】:

以上答案就足够了 - 您必须根据您的场景使用 JavaScript。似乎麻烦在于从动态网页到动态 HTML 的飞跃。

在此处阅读摘要的最后一行: https://en.wikipedia.org/wiki/Dynamic_HTML

【讨论】:

    【解决方案2】:

    在您取回数据后,您需要使用 javascript 来修改您的表格。由于您已经在使用 jQuery,因此您有工具可以让这变得非常简单。

    您的问题可以分为两个步骤:确定要更新的页面的正确部分,然后修改感兴趣的单元格。

    识别正确的单元格被简化了,因为传递给您的函数的鼠标事件包含对被点击事物的引用。

    为了更容易找到表格的正确部分,最好给每个&lt;td&gt; 一个类:

    // Status column
    <td class="status-column">
        // your php status stuff from above
    </td>
    
    // Button column
    <td class="activate-column">
        // your php button-drawing stuff from above
    </td>
    

    现在很容易找到您要修改的内容。

    这是您的 ajax 调用,其中添加了一些用于重绘相关单元格的内容:

    $('.state-change').on('click', function(evt) {
        evt.preventDefault();
        var id = $(this).data('id');
        var role = $(this).data('role');
        if (role == "activate") {
            var stateUrl = 'users/activate/';
        } else {
            var stateUrl = 'users/deactivate/';
        }
        $.ajax({
            url: stateUrl + id,
            method: 'GET',
            dataType: 'php',
            success: function(){
                console.log(id);
                console.log(role);
    
                // find the row that is the parent of the clicked button - http://api.jquery.com/parent/
                var row = evt.target.parent('tr');
    
                // use the class of the table cell to identify it. http://api.jquery.com/find/
                var statusCell = row.find('.status-column').first();
    
                // now put in the new status. http://api.jquery.com/html/
                if (role == "activate") {
                    statusCell.html('<span class="text-success">Enabled</span>');
                } else {
                    statusCell.html('<span class="text-danger">Disabled</span>');
                }
            }
        });
    });
    

    我会把按钮栏留给你练习:)。

    编辑:您还可以使用非 jQuery 方法操作 DOM,这些方法可能更符合您的喜好。无论如何,这就是 jQuery 在幕后所做的。

    您可以阅读更多关于他们的信息at MDN

    // build the new DOM node
    var newStatusCellContent = document.createElement('span');
    newStatusCellContent.setAttribute('class', role == 'activate' ? 'text-enabled' : 'text-danger');
    newStatusCellContent.textContent = role == 'activate' ? 'Enabled' : 'Disabled';
    
    // get the parent <td> node from the jQuery object
    var statusCell = row.find('.status-column').get(0);
    
    // swap the old contents for the new
    var oldChild = statusCell.childNodes[0]
    statusCell.replaceNode(newStatusCellContent, oldChild);
    

    仔细研究上述链接中的文档可能会发现一些方法可以使您的特定案例更有效。请记住,这与 jQuery html() 方法(或 Angular 或任何其他方法)所做的相同,虽然它使您远离 HTML,但在这种情况下它并没有真正改进您的代码。我真的很讨厌 HTML,但这是我们提供的工具。

    注意php也有DOM库;如果您愿意,您也可以使用它们来构建您的原始页面,并永远使用 HTML。但我不推荐它,除非在某些情况下。

    【讨论】:

    • 看起来不错,但正如我所提到的,statusCell.html('&lt;span class="text-success"&gt;Enabled&lt;/span&gt;'); 是我希望避免的。使用 AngularJS 代替 AJAX 会是个好主意吗?
    • 每个表行都有一个id属性等于用户的id。
    • 我猜关键是:你为什么不想用这个方法?当你去掉语法上的差异时,Angular 会做同样的事情。你有一个选择:修改页面,或者重新加载它。在这种情况下,修改页面是更好的选择。
    • 请注意,我添加了使用原生 javascript 而不是 jQuery 的代码,它以面向对象的方式构建新的 DOM 对象。
    • var statusCell = row.find('.status-column').first(); 的意义何在?它有什么作用?
    猜你喜欢
    • 2017-06-08
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多