1. 程式人生 > >js中回撥函式的運用

js中回撥函式的運用

在javascript中,會經常用到回撥的方式,比如,當某一請求執行完成後,要完成某一指定的動作,但是程式無法知道請求什麼時候完成,這時我們便可以使用回撥來實現,像ajax就用到了回撥的概念。下面,筆者列舉自己在專案中用到的兩個例項。

例項一、ajax請求遮罩層的實現

首先,來看看js程式碼:

function postRequest(object, callback) {
  //請求之前,顯示遮罩層,以及loading圖示
  window.top.$('#maskCell').show();
  window.top.$('#loadImg').show();

  $.post(object.url, object.param, function
(data){
//請求成功之後,隱藏遮罩層以及loading圖示 window.top.$('#maskCell').hide(); window.top.$('#loadImg').hide(); callback(data); }); }

再來看看呼叫的js程式碼:

$(function(){
    //Get data by user id
    var id = $('#detailUserId').val();

//  $.getJSON('sys/user/getEntity.do', {'id': id}, function(data) {
// console.log(data); // // //載入資料到表單 // $('#singleUserDlogForm').form('load',data); // }); postRequest({ url:'sys/user/getEntity.do', param: {'id':id} }, function(data) { console.log(data); //載入資料到表單 $('#singleUserDlogForm').form('load',data); }); });

這裡,每當請求完成後去掉遮罩層,並通過回撥完成特定的任務。

例項二、匯入成功後邊重新載入資料

首先,來看看頁面:
這裡寫圖片描述
這裡,點選開始匯入,匯入成功後便要重新載入datagrid。
注意,此匯入視窗在父視窗中,datagrid資料表格在iframe中,所以筆者這裡會將回調函式名從iframe視窗傳到匯入視窗。
下面來看看userlist.jsp頁面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
  String path = request.getContextPath();
  String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Cache-Control" CONTENT="no-cache">
<title>User List</title>
<link rel="stylesheet" type="text/css" href="resources/jquery-easyui-1.4.2/themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="resources/jquery-easyui-1.4.2/themes/icon.css">
<link rel="stylesheet" type="text/css" href="resources/logicCSS/user/listUser.css">
</head>
<body>
<h2>User List</h2>
<div>
<form id="queryForm">
ID:<input type="text" name="id"/> 姓名:<input type="text" name="userName"/> <a href="javascript:void(0);" id="search">搜尋</a>
</form>
</div>
<a type="import" id="import" class="easyui-menubutton" callback="myCallback">匯入</a>
<!-- 匯出 -->
<a type="export" id="export" class="easyui-menubutton">匯出</a>
<!-- 表格 -->
<div data-options="region:'center'" class="tab">
    <table id="userListTab"></table>
</div>

<script type="text/javascript" src="resources/jquery-easyui-1.4.2/jquery-1.8.0.js"></script>
<script type="text/javascript" src="resources/jquery-easyui-1.4.2/jquery.easyui.min.js"></script>
<script type="text/javascript" src="resources/logicJS/common/common.js"></script>
<script type="text/javascript">
var basePath = '<%=basePath %>';
console.log('currentMenu:', window.top.currentMenu);
console.log('basePath:', basePath);
</script>
<script type="text/javascript" src="resources/logicJS/user/listUser.js"></script>

</body>
</html>

然後,再來看看其對應的listUser.js:

$(function() {
  console.log('windows是否一致', window === window.top);

  //初始化匯出按鈕
  initMyExportMenu();

    //新增搜尋按鈕點選事件
    $('#search').click(function() {
        search();
    });

    //新增匯入點選事件
    $('#import').click(function() {
      console.log('彈出匯入對話方塊。。');

      //獲取回撥函式名
      var callbackName = $(this).attr('callback');

      //使用者詳情對話方塊
      var importWindow = window.top.$('#importWin');
      if(importWindow.length <= 0) {
        importWindow = window.top.$("<div id='importWin'/>").appendTo(window.top.document.body);
      }
      importWindow.window({
        title:'匯入',
        closed: false,
        closable: true,
        draggable: true,
        resizable: true,
        width: 400,
        height: 300,
        modal: true,
        href: 'sys/redirect/redirectHomePage.do?path=import&callback=' + callbackName,
        onClose: function() {
          importWindow.window("destroy");
        }
      });
    });

    //載入userlist到datagrid中去,使用datagrid預設分頁機制
    $("#userListTab").datagrid({
        fit:true,
        fitColumns:true,
        collapsible:false,
        nowrap: true,
        autoRowHeight: true,
        striped: true,
        url: 'sys/user/getPageModel.do',
        idField : 'id',
        remoteSort: true,
        loadMsg: 'Please wait...',
        checkOnSelect:false,
        singleSelect: false,
        frozenColumns:[[
          {field:'ck',checkbox:true}
        ]],
        columns:[[
        {field:'id',title:'使用者id',sortable:true},
          {field:'userName',title:'使用者姓名',sortable:true},
          {field:'age',title:'使用者年齡',sortable:true},
          {field:'opt',title:'操作', align:'center', formatter:function(value,rec, index) {
              return '<a id="detail" href="javascript:void(0);" onclick="detail(' + rec.id +')">檢視</a> <a id="edit" href="javascript:void(0);" onclick="edit(' + rec.id + ')">編輯</a> <a id="delete" href="javascript:void(0);" onclick="deleteUser(' + rec.id + ')">刪除</a>';
          }}
        ]],
        //工具欄:新增、批量刪除
        toolbar: [{
            id: 'btnAdd',
            text: 'Add',
            iconCls:'icon-add',
            handler:function() {
                edit();
            }
        }, '-', {
            id:'btnDelete',
            text: 'Delete',
            iconCls:'icon-cut',
            handler: function() {
                var rows =  $("#userListTab").datagrid('getChecked');
                var array = [];
                $.each(rows, function(index, row){
                    array.push(row.id);
                });
                deleteUser(array);
            }
        }],
        pagination:true,
        pageSize: 5,
        pageList: [3,4,5],
        onLoadSuccess:function(data){
            console.log(data);
        }
    });

    //分頁
    var p = $('#userListTab').datagrid('getPager');
    $(p).pagination({
        beforePageText: '第',//頁數文字框前顯示的漢字 
        afterPageText: '頁    共 {pages} 頁', 
        displayMsg: '當前顯示 {from} - {to} 條記錄   共 {total} 條記錄',  
            onBeforeRefresh:function(){}
            //onSelectPage: function(pageNumber, pageSize) {} --此事件新增,就會導致當頁碼或頁大小變化時,不向後臺傳送請求
    });

});

//檢視詳情
function detail(id) {
    //使用者詳情對話方塊
    var addWindow = window.top.$('#detailWin');
    if(addWindow.length <= 0) {
        addWindow = window.top.$("<div id='detailWin'/>").appendTo(window.top.document.body);
    }
    addWindow.window({
        title:'使用者詳情',
        closed: false,
        closable: true,
        draggable: true,
        resizable: true,
        width: 900,
        height: 600,
        modal: true,
        href: 'sys/redirect/redirectHomePage.do?path=user_detail&id=' + id,
        onClose: function() {
            addWindow.window("destroy");
        }
    });
}

//新增和編輯,共用
function edit(id) {
    //編輯使用者對話方塊
    var addWindow = window.top.$('#saveOrEditUserWin');
    if(addWindow.length <= 0) {
        addWindow = window.top.$("<div id='saveOrEditUserWin'/>").appendTo(window.top.document.body);
    }
    addWindow.window({
        title:'新增和編輯使用者',
        closed: false,
        closable: true,
        draggable: true,
        resizable: true,
        width: 900,
        height: 600,
        modal: true,
        href: 'sys/redirect/redirectHomePage.do?path=user_save&id=' + id,
        onClose: function() {
            addWindow.window("destroy");
        }
    });
}

//刪除
function deleteUser(ids) {
    var array = [];

    //判斷是單個刪除,還是多個刪除
    if(typeof(ids) === 'number') {
        array.push(ids);
    } else {
        array = ids;
    }

    //刪除確認
    window.top.$.messager.confirm('警告', '你確定要刪除嗎?', function(result){
        if(result) {
//          $.post(baseURL + '/user/deleteEntity.do', {ids: array}, function(data){
//              window.top.$.messager.alert('提示', '刪除成功!!');
//              
//              //Reload data
//              $("#userListTab").datagrid('reload');          
//          });
            postRequest({
            url: 'sys/user/deleteEntity.do',
            param: {ids: array}
          }, function(data) {
        window.top.$.messager.alert('提示', '刪除成功!!');

        //Reload data
        $("#userListTab").datagrid('reload'); 
          });
        }
    }); 
}

//搜尋
function search() {
    var params = []; 
    //自動序列化表單元素為JSON物件 
    var fields =$('#queryForm').serializeArray(); 
    console.log(fields);
    $.each(fields, function(i, field){  
        if(field.name === 'id' && $.trim(field.value) === '') {
            field.value = 0;
        }
        params[field.name] = field.value; 
    });  
    console.log('params', params['userName']);
    //重新載入資料
    $('#userListTab').datagrid('load',params); 
}

/**
 * 初始化匯出按鈕
 */
function initMyExportMenu(){
  var exportsubmenu = '<div id="exportMenu_sub">'+
  '<div id="export_crrent"><span class="exportcurrent"></span>匯出當前頁</div>'+
  '<h1 class="excel-line"></h1>'+
  '<div id="export_all"><span class="exportall"></span>匯出全部</div>'+
  '</div>';
  $("body").append(exportsubmenu);
  var exports = $("a[type='export']");
  $.each(exports,function(data){

    var exportMenu = $(this).menubutton({ 
      menu: "#exportMenu_sub",
      iconCls:"icon-export"

    }); 
    $(exportMenu.menubutton('options').menu).menu({
      onHide:function(){
      },
      onClick: function (item) {
      if(item.id=="export_crrent"){
        console.log('匯出當前頁');
        var options = $('#userListTab').datagrid('getPager').data("pagination").options;
        var curr = options.pageNumber;
        console.log('當前頁:', curr);
        var pageSize = options.pageSize;
        console.log('頁大小', pageSize);

        //通過隱藏域傳引數

//        $("#queryForm").form('submit',{
//              url : 'tm/illegalBusinessWebsiteDetail/exportillegalBusiness.do',
//              onSubmit : function() {
//                return $(this).form('validate');
//              },
//              success : function(data) {
//              }
//         });

      }
      if(item.id=="export_all"){
        console.log('匯出全部');
//        $("#queryForm").form('submit',{
//          url : 'tm/illegalBusinessWebsiteDetail/exportillegalBusiness.do',
//          onSubmit : function() {
//            return $(this).form('validate');
//          },
//          success : function(data) {
//          }
//         });

      }

      }
    });

  });
}

/**
 * 回撥函式
 * @returns
 */
function myCallback(name) {
  console.log('回撥函式執行。。' + name);
  //重新載入datagrid
  $("#userListTab").datagrid('reload'); 
}

最後,再來看匯入視窗頁面import.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
  String callback = request.getParameter("callback");
  System.out.println("回撥函式為:" + callback);
%>
<script type="text/javascript">
var callback = '<%=callback%>';
console.log('callback:', callback);
</script>
<div style="width:100%;height:100%;position:relative;">
    <button id="startImport" style="position:relative;top:224px;left:50px;height:20px;">開始匯入</button>
</div>

<script type="text/javascript" src="resources/logicJS/common/common.js"></script>
<script type="text/javascript" src="resources/logicJS/common/import.js"></script>

其對應的js,import.js:

$(function() {
  console.log('windows是否一致', window === window.top);
  $('#startImport').click(function() {
    console.log('開始匯入');

    var iframe = $('#mainPanel > iframe' ,window.top.document)[0];
    var currentChildWindow = iframe.contentWindow || iframe.window;
    console.log('callback', callback);
    currentChildWindow[callback]('qiyongkang');
  });
});

最後,點選‘開始匯入’按鈕後,控制檯的輸入如下圖:
這裡寫圖片描述
說明,回撥成功啦!
今天,就講到這兒啦,有些沒講清楚或是有問題的地方,歡迎大家指出,謝謝!