用Twitter引导确认删除模式/对话框?
我有一个绑定到数据库行的HTML表格。 我想每行有一个“删除行”链接,但是我想事先与用户确认。 有没有办法使用Twitter引导modal dialog做到这一点?
获取配方
对于这个任务,您可以使用已经可用的插件和引导程序扩展。 或者您可以使用三行代码进行自己的确认popup窗口。 一探究竟。
假设我们有这个链接(注意data-href
而不是href
)或者我们想要删除确认的button:
<a href="#" data-href="delete.php?id=23" data-toggle="modal" data-target="#confirm-delete">Delete record #23</a> <button class="btn btn-default" data-href="/delete.php?id=54" data-toggle="modal" data-target="#confirm-delete"> Delete record #54 </button>
在这里#confirm-delete
指向您的HTML模式popup的div。 它应该有一个像这样configuration的“确定”button:
<div class="modal fade" id="confirm-delete" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> ... </div> <div class="modal-body"> ... </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> <a class="btn btn-danger btn-ok">Delete</a> </div> </div> </div> </div>
现在你只需要这个小小的JavaScript来做一个可以确定的删除动作:
$('#confirm-delete').on('show.bs.modal', function(e) { $(this).find('.btn-ok').attr('href', $(e.relatedTarget).data('href')); });
所以在show.bs.modal
事件删除buttonhref
被设置为具有相应loggingID的URL。
演示: http : //plnkr.co/edit/NePR0BQf3VmKtuMmhVR7?p=preview
POST食谱
我意识到,在某些情况下可能需要执行POST或DELETE请求,而不是GET。 它仍然非常简单,没有太多的代码。 用下面的方法看看下面的演示:
// Bind click to OK button within popup $('#confirm-delete').on('click', '.btn-ok', function(e) { var $modalDiv = $(e.delegateTarget); var id = $(this).data('recordId'); $modalDiv.addClass('loading'); $.post('/api/record/' + id).then(function() { $modalDiv.modal('hide').removeClass('loading'); }); }); // Bind to modal opening to set necessary data properties to be used to make request $('#confirm-delete').on('show.bs.modal', function(e) { var data = $(e.relatedTarget).data(); $('.title', this).text(data.recordTitle); $('.btn-ok', this).data('recordId', data.recordId); });
// Bind click to OK button within popup $('#confirm-delete').on('click', '.btn-ok', function(e) { var $modalDiv = $(e.delegateTarget); var id = $(this).data('recordId'); $modalDiv.addClass('loading'); setTimeout(function() { $modalDiv.modal('hide').removeClass('loading'); }, 1000); // In reality would be something like this // $modalDiv.addClass('loading'); // $.post('/api/record/' + id).then(function() { // $modalDiv.modal('hide').removeClass('loading'); // }); }); // Bind to modal opening to set necessary data properties to be used to make request $('#confirm-delete').on('show.bs.modal', function(e) { var data = $(e.relatedTarget).data(); $('.title', this).text(data.recordTitle); $('.btn-ok', this).data('recordId', data.recordId); });
.modal.loading .modal-content:before { content: 'Loading...'; text-align: center; line-height: 155px; font-size: 20px; background: rgba(0, 0, 0, .8); position: absolute; top: 55px; bottom: 0; left: 0; right: 0; color: #EEE; z-index: 1000; }
<script data-require="jquery@*" data-semver="2.0.3" src="//code.jquery.com/jquery-2.0.3.min.js"></script> <script data-require="bootstrap@*" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> <link data-require="bootstrap-css@3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" /> <div class="modal fade" id="confirm-delete" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title" id="myModalLabel">Confirm Delete</h4> </div> <div class="modal-body"> <p>You are about to delete <b><i class="title"></i></b> record, this procedure is irreversible.</p> <p>Do you want to proceed?</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-danger btn-ok">Delete</button> </div> </div> </div> </div> <a href="#" data-record-id="23" data-record-title="The first one" data-toggle="modal" data-target="#confirm-delete"> Delete "The first one", #23 </a> <br /> <button class="btn btn-default" data-record-id="54" data-record-title="Something cool" data-toggle="modal" data-target="#confirm-delete"> Delete "Something cool", #54 </button>
http://bootboxjs.com/ – 与Bootstrap 3.0.0的最新作品
最简单的例子:
bootbox.alert("Hello world!");
来自网站:
这个库提供了三种方法来模仿他们原生的JavaScript等价物。 他们的确切的方法签名是灵活的,因为每个可以采取各种参数来定制标签和指定默认值,但他们通常被这样调用:
bootbox.alert(message, callback) bootbox.prompt(message, callback) bootbox.confirm(message, callback)
这是它的一个片段(点击下面的“运行代码片段”):
$(function() { bootbox.alert("Hello world!"); });
<!-- required includes --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/> <!-- bootbox.js at 4.4.0 --> <script src="https://rawgit.com/makeusabrew/bootbox/f3a04a57877cab071738de558581fbc91812dce9/bootbox.js"></script>
// ---------------------------------------------------------- Generic Confirm function confirm(heading, question, cancelButtonTxt, okButtonTxt, callback) { var confirmModal = $('<div class="modal hide fade">' + '<div class="modal-header">' + '<a class="close" data-dismiss="modal" >×</a>' + '<h3>' + heading +'</h3>' + '</div>' + '<div class="modal-body">' + '<p>' + question + '</p>' + '</div>' + '<div class="modal-footer">' + '<a href="#" class="btn" data-dismiss="modal">' + cancelButtonTxt + '</a>' + '<a href="#" id="okButton" class="btn btn-primary">' + okButtonTxt + '</a>' + '</div>' + '</div>'); confirmModal.find('#okButton').click(function(event) { callback(); confirmModal.modal('hide'); }); confirmModal.modal('show'); }; // ---------------------------------------------------------- Confirm Put To Use $("i#deleteTransaction").live("click", function(event) { // get txn id from current table row var id = $(this).data('id'); var heading = 'Confirm Transaction Delete'; var question = 'Please confirm that you wish to delete transaction ' + id + '.'; var cancelButtonTxt = 'Cancel'; var okButtonTxt = 'Confirm'; var callback = function() { alert('delete confirmed ' + id); }; confirm(heading, question, cancelButtonTxt, okButtonTxt, callback); });
我会意识到这是一个非常古老的问题,但因为我想知道今天更有效的方法来处理自举模态。 我做了一些研究,发现了一些比上面显示的解决scheme更好的东西,可以在这个链接中find:
http://www.petefreitag.com/item/809.cfm
首先加载jquery
$(document).ready(function() { $('a[data-confirm]').click(function(ev) { var href = $(this).attr('href'); if (!$('#dataConfirmModal').length) { $('body').append('<div id="dataConfirmModal" class="modal" role="dialog" aria-labelledby="dataConfirmLabel" aria-hidden="true"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button><h3 id="dataConfirmLabel">Please Confirm</h3></div><div class="modal-body"></div><div class="modal-footer"><button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button><a class="btn btn-primary" id="dataConfirmOK">OK</a></div></div>'); } $('#dataConfirmModal').find('.modal-body').text($(this).attr('data-confirm')); $('#dataConfirmOK').attr('href', href); $('#dataConfirmModal').modal({show:true}); return false; }); });
然后,只要问任何问题/确认href:
<a href="/any/url/delete.php?ref=ID" data-confirm="Are you sure you want to delete?">Delete</a>
这种方式确认模式是非常普遍的,所以它可以很容易地在您的网站的其他部分重新使用。
感谢@ Jousby的解决scheme ,我设法让我的工作,但发现我不得不改善他的解决scheme的Bootstrap模式标记一点,使正确的渲染正确的例子中所示 。
所以,这是我工作正常的通用confirm
函数的修改版本:
/* Generic Confirm func */ function confirm(heading, question, cancelButtonTxt, okButtonTxt, callback) { var confirmModal = $('<div class="modal fade">' + '<div class="modal-dialog">' + '<div class="modal-content">' + '<div class="modal-header">' + '<a class="close" data-dismiss="modal" >×</a>' + '<h3>' + heading +'</h3>' + '</div>' + '<div class="modal-body">' + '<p>' + question + '</p>' + '</div>' + '<div class="modal-footer">' + '<a href="#!" class="btn" data-dismiss="modal">' + cancelButtonTxt + '</a>' + '<a href="#!" id="okButton" class="btn btn-primary">' + okButtonTxt + '</a>' + '</div>' + '</div>' + '</div>' + '</div>'); confirmModal.find('#okButton').click(function(event) { callback(); confirmModal.modal('hide'); }); confirmModal.modal('show'); }; /* END Generic Confirm func */
我发现这个有用和易于使用,再加上它看起来很漂亮: http : //maxailloud.github.io/confirm-bootstrap/ 。
要使用它,请在页面中包含.js文件,然后运行:
$('your-link-selector').confirmModal();
有很多选项可以应用到它,使它看起来更好,当它来确认一个删除,我使用:
$('your-link-selector').confirmModal({ confirmTitle: 'Please confirm', confirmMessage: 'Are you sure you want to delete this?', confirmStyle: 'danger', confirmOk: '<i class="icon-trash icon-white"></i> Delete', confirmCallback: function (target) { //perform the deletion here, or leave this option //out to just follow link.. } });
我可以使用bootbox.js库轻松处理这种types的任务。 首先你需要包含bootbox JS文件。 然后在你的事件处理函数中写下面的代码:
bootbox.confirm("Are you sure to want to delete , function(result) { //here result will be true // delete process code goes here });
官方bootboxjs 网站
以下解决scheme比bootbox.js更好 ,因为
- 它可以做一切bootbox.js可以做的;
- 使用语法更简单
- 它允许您使用“错误”,“警告”或“信息”来优雅地控制消息的颜色
- Bootbox是986线长,我的只有110线长
digimango.messagebox.js :
const dialogTemplate = '\ <div class ="modal" id="digimango_messageBox" role="dialog">\ <div class ="modal-dialog">\ <div class ="modal-content">\ <div class ="modal-body">\ <p class ="text-success" id="digimango_messageBoxMessage">Some text in the modal.</p>\ <p><textarea id="digimango_messageBoxTextArea" cols="70" rows="5"></textarea></p>\ </div>\ <div class ="modal-footer">\ <button type="button" class ="btn btn-primary" id="digimango_messageBoxOkButton">OK</button>\ <button type="button" class ="btn btn-default" data-dismiss="modal" id="digimango_messageBoxCancelButton">Cancel</button>\ </div>\ </div>\ </div>\ </div>'; // See the comment inside function digimango_onOkClick(event) { var digimango_numOfDialogsOpened = 0; function messageBox(msg, significance, options, actionConfirmedCallback) { if ($('#digimango_MessageBoxContainer').length == 0) { var iDiv = document.createElement('div'); iDiv.id = 'digimango_MessageBoxContainer'; document.getElementsByTagName('body')[0].appendChild(iDiv); $("#digimango_MessageBoxContainer").html(dialogTemplate); } var okButtonName, cancelButtonName, showTextBox, textBoxDefaultText; if (options == null) { okButtonName = 'OK'; cancelButtonName = null; showTextBox = null; textBoxDefaultText = null; } else { okButtonName = options.okButtonName; cancelButtonName = options.cancelButtonName; showTextBox = options.showTextBox; textBoxDefaultText = options.textBoxDefaultText; } if (showTextBox == true) { if (textBoxDefaultText == null) $('#digimango_messageBoxTextArea').val(''); else $('#digimango_messageBoxTextArea').val(textBoxDefaultText); $('#digimango_messageBoxTextArea').show(); } else $('#digimango_messageBoxTextArea').hide(); if (okButtonName != null) $('#digimango_messageBoxOkButton').html(okButtonName); else $('#digimango_messageBoxOkButton').html('OK'); if (cancelButtonName == null) $('#digimango_messageBoxCancelButton').hide(); else { $('#digimango_messageBoxCancelButton').show(); $('#digimango_messageBoxCancelButton').html(cancelButtonName); } $('#digimango_messageBoxOkButton').unbind('click'); $('#digimango_messageBoxOkButton').on('click', { callback: actionConfirmedCallback }, digimango_onOkClick); $('#digimango_messageBoxCancelButton').unbind('click'); $('#digimango_messageBoxCancelButton').on('click', digimango_onCancelClick); var content = $("#digimango_messageBoxMessage"); if (significance == 'error') content.attr('class', 'text-danger'); else if (significance == 'warning') content.attr('class', 'text-warning'); else content.attr('class', 'text-success'); content.html(msg); if (digimango_numOfDialogsOpened == 0) $("#digimango_messageBox").modal(); digimango_numOfDialogsOpened++; } function digimango_onOkClick(event) { // JavaScript's nature is unblocking. So the function call in the following line will not block, // thus the last line of this function, which is to hide the dialog, is executed before user // clicks the "OK" button on the second dialog shown in the callback. Therefore we need to count // how many dialogs is currently showing. If we know there is still a dialog being shown, we do // not execute the last line in this function. if (typeof (event.data.callback) != 'undefined') event.data.callback($('#digimango_messageBoxTextArea').val()); digimango_numOfDialogsOpened--; if (digimango_numOfDialogsOpened == 0) $('#digimango_messageBox').modal('hide'); } function digimango_onCancelClick() { digimango_numOfDialogsOpened--; if (digimango_numOfDialogsOpened == 0) $('#digimango_messageBox').modal('hide'); }
当涉及到一个相关的大项目时,我们可能需要一些可重用的东西。 这是我在SO的帮助下来的。
confirmDelete.jsp
<!-- Modal Dialog --> <div class="modal fade" id="confirmDelete" role="dialog" aria-labelledby="confirmDeleteLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title">Delete Parmanently</h4> </div> <div class="modal-body" style="height: 75px"> <p>Are you sure about this ?</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-danger" id="confirm-delete-ok">Ok </button> </div> </div> </div>
<script type="text/javascript"> var url_for_deletion = "#"; var success_redirect = window.location.href; $('#confirmDelete').on('show.bs.modal', function (e) { var message = $(e.relatedTarget).attr('data-message'); $(this).find('.modal-body p').text(message); var title = $(e.relatedTarget).attr('data-title'); $(this).find('.modal-title').text(title); if (typeof $(e.relatedTarget).attr('data-url') != 'undefined') { url_for_deletion = $(e.relatedTarget).attr('data-url'); } if (typeof $(e.relatedTarget).attr('data-success-url') != 'undefined') { success_redirect = $(e.relatedTarget).attr('data-success-url'); } }); <!-- Form confirm (yes/ok) handler, submits form --> $('#confirmDelete').find('.modal-footer #confirm-delete-ok').on('click', function () { $.ajax({ method: "delete", url: url_for_deletion, }).success(function (data) { window.location.href = success_redirect; }).fail(function (error) { console.log(error); }); $('#confirmDelete').modal('hide'); return false; }); <script/>
reusingPage.jsp
<a href="#" class="table-link danger" data-toggle="modal" data-target="#confirmDelete" data-title="Delete Something" data-message="Are you sure you want to inactivate this something?" data-url="client/32" id="delete-client-32"> </a> <!-- jQuery should come before this --> <%@ include file="../some/path/confirmDelete.jsp" %>
注意:这个使用http delete方法来删除请求,你可以从javascript中改变它,或者可以使用数据标题或数据url等数据属性来发送它,以支持任何请求。
如果你想以最简单的方式做到这一点 ,那么你可以用这个插件来做到这一点 。
但是这个插件是使用Bootstrap模式的替代实现。 而且真正的Bootstrap实现也很容易,所以我不喜欢使用这个插件,因为它在页面中添加了过多的JS内容,这将减慢页面加载时间。
理念
我喜欢用这种方式自己来实现 –
- 如果用户点击一个button来从列表中删除一个项目,那么一个JS调用将把项目ID (或者任何更重要的数据)放在一个表单中。
-
然后在popup的对话框中会出现2个确认button。
- 是的,会提交表格(用ajax或直接表格提交)
- 不,只会解散模态
代码将是这样的(使用Bootstrap ) –
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <script> $(document).ready(function() { $("button").click(function() { //Say - $('p').get(0).id - this delete item id $("#delete_item_id").val( $('p').get(0).id ); $('#delete_confirmation_modal').modal('show'); }); }); </script> <p id="1">This is a item to delete.</p> <button type="button" class="btn btn-danger">Delete</button> <!-- Delete Modal content--> <div class="modal fade" id="delete_confirmation_modal" role="dialog" style="display: none;"> <div class="modal-dialog" style="margin-top: 260.5px;"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">×</button> <h4 class="modal-title">Do you really want to delete this Category?</h4> </div> <form role="form" method="post" action="category_delete" id="delete_data"> <input type="hidden" id="delete_item_id" name="id" value="12"> <div class="modal-footer"> <button type="submit" class="btn btn-danger">Yes</button> <button type="button" class="btn btn-primary" data-dismiss="modal">No</button> </div> </form> </div> </div> </div>
你可以尝试更多的可重用我的解决scheme与callback函数。 在这个函数中你可以使用POST请求或者一些逻辑。 使用库: JQuery 3>和Bootstrap 3> 。
https://jsfiddle.net/axnikitenko/gazbyv8v/
testing的HTML代码:
... <body> <a href='#' id="remove-btn-a-id" class="btn btn-default">Test Remove Action</a> </body> ...
使用Javascript:
$(function () { function remove() { alert('Remove Action Start!'); } // Example of initializing component data this.cmpModalRemove = new ModalConfirmationComponent('remove-data', remove, 'remove-btn-a-id', { txtModalHeader: 'Header Text For Remove', txtModalBody: 'Body For Text Remove', txtBtnConfirm: 'Confirm', txtBtnCancel: 'Cancel' }); this.cmpModalRemove.initialize(); }); //---------------------------------------------------------------------------------------------------------------------- // COMPONENT SCRIPT //---------------------------------------------------------------------------------------------------------------------- /** * Script processing data for confirmation dialog. * Used libraries: JQuery 3> and Bootstrap 3>. * * @param name unique component name at page scope * @param callback function which processing confirm click * @param actionBtnId button for open modal dialog * @param text localization data, structure: * > txtModalHeader - text at header of modal dialog * > txtModalBody - text at body of modal dialog * > txtBtnConfirm - text at button for confirm action * > txtBtnCancel - text at button for cancel action * * @constructor * @author Aleksey Nikitenko */ function ModalConfirmationComponent(name, callback, actionBtnId, text) { this.name = name; this.callback = callback; // Text data this.txtModalHeader = text.txtModalHeader; this.txtModalBody = text.txtModalBody; this.txtBtnConfirm = text.txtBtnConfirm; this.txtBtnCancel = text.txtBtnCancel; // Elements this.elmActionBtn = $('#' + actionBtnId); this.elmModalDiv = undefined; this.elmConfirmBtn = undefined; } /** * Initialize needed data for current component object. * Generate html code and assign actions for needed UI * elements. */ ModalConfirmationComponent.prototype.initialize = function () { // Generate modal html and assign with action button $('body').append(this.getHtmlModal()); this.elmActionBtn.attr('data-toggle', 'modal'); this.elmActionBtn.attr('data-target', '#'+this.getModalDivId()); // Initialize needed elements this.elmModalDiv = $('#'+this.getModalDivId()); this.elmConfirmBtn = $('#'+this.getConfirmBtnId()); // Assign click function for confirm button var object = this; this.elmConfirmBtn.click(function() { object.elmModalDiv.modal('toggle'); // hide modal object.callback(); // run callback function }); }; //---------------------------------------------------------------------------------------------------------------------- // HTML GENERATORS //---------------------------------------------------------------------------------------------------------------------- /** * Methods needed for get html code of modal div. * * @returns {string} html code */ ModalConfirmationComponent.prototype.getHtmlModal = function () { var result = '<div class="modal fade" id="' + this.getModalDivId() + '"'; result +=' tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">'; result += '<div class="modal-dialog"><div class="modal-content"><div class="modal-header">'; result += this.txtModalHeader + '</div><div class="modal-body">' + this.txtModalBody + '</div>'; result += '<div class="modal-footer">'; result += '<button type="button" class="btn btn-default" data-dismiss="modal">'; result += this.txtBtnCancel + '</button>'; result += '<button id="'+this.getConfirmBtnId()+'" type="button" class="btn btn-danger">'; result += this.txtBtnConfirm + '</button>'; return result+'</div></div></div></div>'; }; //---------------------------------------------------------------------------------------------------------------------- // UTILITY //---------------------------------------------------------------------------------------------------------------------- /** * Get id element with name prefix for this component. * * @returns {string} element id */ ModalConfirmationComponent.prototype.getModalDivId = function () { return this.name + '-modal-id'; }; /** * Get id element with name prefix for this component. * * @returns {string} element id */ ModalConfirmationComponent.prototype.getConfirmBtnId = function () { return this.name + '-confirm-btn-id'; };
带有导航到目标页面和可重复使用的刀片文件的POST配方
dfsq的回答非常好。 我修改了一下,以适应我的需要:我实际上需要一个模式的情况下,点击后,用户也将被导航到相应的页面。 asynchronous执行查询并不总是需要的。
使用Blade
我创build了文件resources/views/includes/confirmation_modal.blade.php
:
<div class="modal fade" id="confirmation-modal" tabindex="-1" role="dialog" aria-labelledby="confirmation-modal-label" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h4>{{ $headerText }}</h4> </div> <div class="modal-body"> {{ $bodyText }} </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button> <form action="" method="POST" style="display:inline"> {{ method_field($verb) }} {{ csrf_field() }} <input type="submit" class="btn btn-danger btn-ok" value="{{ $confirmButtonText }}" /> </form> </div> </div> </div> </div> <script> $('#confirmation-modal').on('show.bs.modal', function(e) { href = $(e.relatedTarget).data('href'); // change href of button to corresponding target $(this).find('form').attr('action', href); }); </script>
现在,使用它是直截了当的:
<a data-href="{{ route('data.destroy', ['id' => $data->id]) }}" data-toggle="modal" data-target="#confirmation-modal" class="btn btn-sm btn-danger">Remove</a>
这里没有太多的改变,模态可以像这样包括:
@include('includes.confirmation_modal', ['headerText' => 'Delete Data?', 'bodyText' => 'Do you really want to delete these data? This operation is irreversible.', 'confirmButtonText' => 'Remove Data', 'verb' => 'DELETE'])
只要把动词放在那里,它就会使用它。 这样,CSRF也被利用。
帮助了我,也许它帮助别人。