zoukankan      html  css  js  c++  java
  • FastAdmin 基本知识流程一栏

     

    fastadmin进阶

    安装:出现登陆页无法显示:可能是php的gd2扩展未开启

    FastAdmin 在 Nginx 中的配置

    用的是AdminLTE后台模板require.js、less、Bower

    调试错误:看runtime/log

    FastAdmin 的上传代码在哪里?

    一张图解析FastAdmin中的表格列表的功能

    fastadmin的页面是如何生成的?

    FastAdmin 如何隐藏操作栏中的“删除”按钮“?

    笔记:FastAdmin 上传设置

    如何修改 FastAdmin 弹窗大小?

    FastAdmin 的 CRUD 不支持层级模型

    fastadmin笔记,应该能解决大部分问题

    一键生成数据表的crud 的记录会保存到fa_command表中

     当在线命令行管理成功生成crud时生成的文件如下:如fa_tom

    application/admin/contorller/Tom.php
    
    application/admin/model/Tom.php
    
    application/admin/validate/Tom.php
    
    application/admin/view/tom/index.html、edit.html、add.html
    
    application/admin/lang/zh-cn/tom.php
    
    /public/assets/js/backend/tom.js

    如果是fa_demo_tom则会生成(_分隔成目录)

    application/admin/contorller/demo/Tom.php
    
    application/admin/model/demo/Tom.php
    
    application/admin/validate/demo/Tom.php
    
    application/admin/view/demo/tom/index.html、edit.html、add.html
    
    application/admin/lang/zh-cn/demo/tom.php
    
    /public/assets/js/backend/demo/tom.js

    生成菜单的记录会更新fa_auth_rule的数据   name不带方法的就是菜单显示的pidwei0是选项卡

    一键生成的是层级目录的菜单,在后台展示时父级菜单会以目录名称显示,

    如上面的contorller/demo/Tom.php  父菜单显示demo子菜单显示Tom ,我们必须在application/admin/lang/zh-cn.php中添加

    'Demo'=>'案例','Tom'=>'案例1'     配置后菜单显示如上:

    一键压缩打包(略)

    在FastAdmin中如果修改了核心的JS或CSS文件,是需要重新压缩打包后在生产环境下才会生效。FastAdmin采用的是基于RequireJSr.js进行JS和CSS文件的压缩打包,application/config.phpapp_debug的值,当为true的时候是采用的无压缩的JS和CSS,当为false时采用的是压缩版的JS和CSS

    多语言:

    return[

    'Home'=>'前台'

    ];

    {:__('Home')}的方式调用,而在PHP和JS中均可以使用__('Home')的方式发起调用

    如果我们需要跨模块引入其它模块的语言包,则可以在 控制器中使用loadlang方法来引入,如

    $this->loadlang('模块名');

    如果需要在JS中跨模块引入语言包,则需要修改Ajax.php中的lang这个方法

    控制器

    我们的控制器都必须继承自application/common/controller/Backend.php的appcommoncontrollerBackend这个基类

    这个基类application/admin/library/traits/Backend.php里引入的 use appadminlibrary raitsBackend;它有八个公共方法

    index/add/edit/del/multi/recyclebin/destroy/restore/                                 import

    查看、添加、编辑、删除、批量更新、回收站、真实删除、还原               导入

    common/controller/Backend里还有好多属性:

    /**
     * 无需登录的方法,同时也就不需要鉴权了
     * @var array
     */
    protected $noNeedLogin = [];
    
    /**
     * 无需鉴权的方法,但需要登录
     * @var array
     */
    protected $noNeedRight = [];
    
    /**
     * 布局模板
     * @var string
     */
    protected $layout = 'default';
    
    /**
     * 权限控制类
     * @var Auth
     */
    protected $auth = null;
    
    /**
     * 快速搜索时执行查找的字段
     */
    protected $searchFields = 'id';
    
    /**
     * 是否是关联查询
     */
    protected $relationSearch = false;
    
    /**
     * 是否开启数据限制
     * 支持auth/personal
     * 表示按权限判断/仅限个人 
     * 默认为禁用,若启用请务必保证表中存在admin_id字段
     */
    protected $dataLimit = false;
    
    /**
     * 数据限制字段
     */
    protected $dataLimitField = 'admin_id';
    
    /**
     * 是否开启Validate验证
     */
    protected $modelValidate = false;
    
    /**
     * 是否开启模型场景验证
     */
    protected $modelSceneValidate = false;
    
    /**
     * Multi方法可批量修改的字段
     */
    protected $multiFields = 'status';
    
    
    
    
    方法
    
    /**
     * 加载语言文件
     * @param string $name
     */
    protected function loadlang($name)
    {
    }
    
    /**
     * 渲染配置信息
     * @param mixed $name 键名或数组
     * @param mixed $value 值 
     */
    protected function assignconfig($name, $value = '')
    {    
    }
    
    /**
     * 生成查询所需要的条件,排序方式
     * @param mixed $searchfields 快速查询的字段
     * @param boolean $relationSearch 是否关联查询
     * @return array
     */
    protected function buildparams($searchfields = null, $relationSearch = null)
    {    
    }
    
    /**
     * 获取数据限制的管理员ID
     * 禁用数据限制时返回的是null
     * @return mixed
     */
    protected function getDataLimitAdminIds()
    {    
    }
    
    /**
     * Selectpage的实现方法
     * 
     * 当前方法只是一个比较通用的搜索匹配,请按需重载此方法来编写自己的搜索逻辑,$where按自己的需求写即可
     * 这里示例了所有的参数,所以比较复杂,实现上自己实现只需简单的几行即可
     * 
     */
    protected function selectpage()
    {
    }

    当两张相似的表意见curd时一个没有关联模型查询一个有时的区别:

    class Demo extends Backend
    {
        
        /**
         * Demo模型对象
         * @var appadminmodelDemo
         */
        protected $model = null;
    
        public function _initialize()
        {
            parent::_initialize();
            $this->model = new appadminmodelDemo;
    
        }
        
        /**
         * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
         * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
         * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
         */
        
    
    }

    traits  的原idnex方法

    trait Backend
    {
    
        /**
         * 查看
         */
        public function index()
        {
            //设置过滤方法
            $this->request->filter(['strip_tags']);
            if ($this->request->isAjax()) {
                //如果发送的来源是Selectpage,则转发到Selectpage
                if ($this->request->request('keyField')) {
                    return $this->selectpage();
                }
                list($where, $sort, $order, $offset, $limit) = $this->buildparams();
                $total = $this->model
                    ->where($where)
                    ->order($sort, $order)
                    ->count();
    
                $list = $this->model
                    ->where($where)
                    ->order($sort, $order)
                    ->limit($offset, $limit)
                    ->select();
    
                $list = collection($list)->toArray();
                $result = array("total" => $total, "rows" => $list);
    
                return json($result);
            }
            return $this->view->fetch();
        }
        //......
    }

    有关联时的控制器:

    class Dash extends Backend
    {
        
        /**
         * Dash模型对象
         * @var appadminmodelDash
         */
        protected $model = null;
    
        public function _initialize()
        {
            parent::_initialize();
            $this->model = new appadminmodelDash;
    
        }
        
        /**
         * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
         * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
         * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
         */
        
    
        /**
         * 查看
         */
        public function index()
        {
            //当前是否为关联查询
            $this->relationSearch = true;
            //设置过滤方法
            $this->request->filter(['strip_tags']);
            if ($this->request->isAjax())
            {
                //如果发送的来源是Selectpage,则转发到Selectpage
                if ($this->request->request('keyField'))
                {
                    return $this->selectpage();
                }
                list($where, $sort, $order, $offset, $limit) = $this->buildparams();
                $total = $this->model
                        ->with(['category'])
                        ->where($where)
                        ->order($sort, $order)
                        ->fetchSql(false)
                        ->count();
    
                $list = $this->model
                        ->with(['category'])
                        ->where($where)
                        ->order($sort, $order)
                        ->limit($offset, $limit)
                        ->fetchSql(false)
                        ->select();
                //file_put_contents(__DIR__.'/../../../runtime/log/sql_'.time().'_log.txt', $total);            
                //file_put_contents(__DIR__.'/../../../runtime/log/sql_'.time().'_log1.txt', $list);            
                foreach ($list as $row) {
                    
                    
                }
                $list = collection($list)->toArray();
                $result = array("total" => $total, "rows" => $list);
    
                return json($result);
            }
            return $this->view->fetch();
        }
    }

    无关联时的model

    class Demo extends Model
    {
        // 表名
        protected $name = 'demo';
        
        // 自动写入时间戳字段
        protected $autoWriteTimestamp = false;
    
        // 定义时间戳字段名
        protected $createTime = false;
        protected $updateTime = false;
        
        // 追加属性
        protected $append = [
        ];
    }

    有关联时的model(多出了一个方法)

    class Dash extends Model
    {
        // 表名
        protected $name = 'dash';
        
        // 自动写入时间戳字段
        protected $autoWriteTimestamp = false;
    
        // 定义时间戳字段名
        protected $createTime = false;
        protected $updateTime = false;
        
        // 追加属性
        protected $append = [
    
        ];
        
        public function category()
        {
            return $this->belongsTo('Category', 'category_id', 'id', [], 'LEFT')->setEagerlyType(0);
        }
    }

    js

    define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
    
        var Controller = {
            index: function () {
                // 初始化表格参数配置
                Table.api.init({
                    extend: {
                        index_url: 'demo/index',
                        add_url: 'demo/add',
                        edit_url: 'demo/edit',
                        del_url: 'demo/del',
                        multi_url: 'demo/multi',
                        table: 'demo',
                    }
                });
    
                var table = $("#table");
    
                // 初始化表格
                table.bootstrapTable({
                    url: $.fn.bootstrapTable.defaults.extend.index_url,
                    pk: 'id',
                    sortName: 'id',
                    columns: [
                        [
                            {checkbox: true},
                            {field: 'id', title: __('Id')},
                            {field: 'name', title: __('Name')},
                            {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
                        ]
                    ]
                });
    
                // 为表格绑定事件
                Table.api.bindevent(table);
            },
            add: function () {
                Controller.api.bindevent();
            },
            edit: function () {
                Controller.api.bindevent();
            },
            api: {
                bindevent: function () {
                    Form.api.bindevent($("form[role=form]"));
                }
            }
        };
        return Controller;
    });

    关联后的js

    define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefined, Backend, Table, Form) {
    
        var Controller = {
            index: function () {
                // 初始化表格参数配置
                Table.api.init({
                    extend: {
                        index_url: 'dash/index',
                        add_url: 'dash/add',
                        edit_url: 'dash/edit',
                        del_url: 'dash/del',
                        multi_url: 'dash/multi',
                        table: 'dash',
                    }
                });
    
                var table = $("#table");
    
                // 初始化表格
                table.bootstrapTable({
                    url: $.fn.bootstrapTable.defaults.extend.index_url,
                    pk: 'id',
                    sortName: 'id',
                    columns: [
                        [
                            {checkbox: true},
                            {field: 'id', title: __('Id')},
                            {field: 'name', title: __('Name')},
                            {field: 'category_id', title: __('Category_id')},
                            {field: 'category.id', title: __('Category.id')},
                            {field: 'category.pid', title: __('Category.pid')},
                            {field: 'category.type', title: __('Category.type')},
                            {field: 'category.name', title: __('Category.name')},
                            {field: 'category.nickname', title: __('Category.nickname')},
                            {field: 'category.flag', title: __('Category.flag'), operate:'FIND_IN_SET', formatter: Table.api.formatter.label},
                            {field: 'category.image', title: __('Category.image'), formatter: Table.api.formatter.image},
                            {field: 'category.keywords', title: __('Category.keywords')},
                            {field: 'category.description', title: __('Category.description')},
                            {field: 'category.diyname', title: __('Category.diyname')},
                            {field: 'category.createtime', title: __('Category.createtime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
                            {field: 'category.updatetime', title: __('Category.updatetime'), operate:'RANGE', addclass:'datetimerange', formatter: Table.api.formatter.datetime},
                            {field: 'category.weigh', title: __('Category.weigh')},
                            {field: 'category.status', title: __('Category.status'), formatter: Table.api.formatter.status},
                            {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
                        ]
                    ]
                });
    
                // 为表格绑定事件
                Table.api.bindevent(table);
            },
            add: function () {
                Controller.api.bindevent();
            },
            edit: function () {
                Controller.api.bindevent();
            },
            api: {
                bindevent: function () {
                    Form.api.bindevent($("form[role=form]"));
                }
            }
        };
        return Controller;
    });

    fastadmin关于table的说明及示例

    bootstraptable详细的参数

    更详细教程

    var table = $("#table");
    
    // 初始化表格
    table.bootstrapTable({
        url: '/Home/GetDepartment',         //请求后台的URL(*)用于从远程站点请求数据的URL
        method: 'get',                      //请求方式(*)
        toolbar: '#toolbar',                //工具栏按钮用哪个容器 一个jQuery 选择器,指明自定义的 buttons toolbar。例如:#buttons-toolbar, .buttons-toolbar 或 DOM 节点
        toolbarAlign:'left'                 //指示如何对齐自定义工具栏。可以使用'left','right'
        buttonsToolbar:'',                  //一个jQuery选择器,指示按钮工具栏,例如:#buttons-toolbar,.buttons-toolbar或DOM节点
        buttonsAlign:'right',               //指示如何对齐工具栏按钮。可以使用'left','right'。
        buttonsClass:'secondary',           //定义表按钮的Bootstrap类(在'btn-'之后添加)
        striped: true,                      //是否显示行间隔色
        cache: false,                       //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
        pagination: true,                   //是否显示分页(*) 设置为true以在表格底部显示分页工具栏默认false
        sortable: true,                     //是否启用排序  列中也有此变量
        sortName:'',                        //定义要排序的列   没定义默认都不排列,同sortOrder结合使用,sortOrder没写的话列默认递增(asc)
        sortOrder: "asc",                   //定义列排序顺序,只能是'asc'或'desc'。
        sortStable: false,                   //如果你把此属性设为了true)我们将为此行添加'_position'属性 (别看错了,是sortStable,sortable在下面)设为true,则和sort部分一样,区别是:在排序过程中,如果存在相等的元素,则原来的顺序不会改变
        queryParams: oTableInit.queryParams,//传递参数(*)
        sidePagination: "server",           //分页方式:client客户端分页(默认),server服务端分页(*)
        silentSort:true,//设置为false以便对加载的消息数据进行排序。当sidePagination选项设置为“server”时,此选项有效。 
        pageNumber:1,                       //初始化加载第一页,默认第一页
        pageSize: 10,                       //每页的记录行数(*)
        pageList: [10, 25, 50, 100],        //可供选择的每页的行数(*)
        search: true,                       //是否显示表格搜索input,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
        strictSearch: true,                 //启用严格搜索
        showColumns: false,                 //是否显示所有的列 设置为true以显示列下拉列表(一个可以设置显示想要的列的下拉f按钮)  
        showRefresh: true,                  //是否显示刷新按钮 默认false
        minimumCountColumns: 1,             //最少允许的列数  要从列下拉列表中隐藏的最小列数
        clickToSelect: true,                //是否启用点击选中行
        height: 500,                        //行高,如果没有设置height属性,表格自动根据记录条数觉得表格高度
        idField:'',                         //表明哪个是字段是标识字段  
        uniqueId: "ID",                     //表明每一行的唯一标识字段,一般为主键列
        showToggle:true,                    //是否显示详细视图和列表视图的切换按钮
        cardView: false,                    //是否显示详细视图  设置为true以显示卡片视图表,例如mobile视图(卡片视图)
        detailView: false,                   //设置为true以显示detail 视图表(细节视图)
        locale:'zh-CN',
        height:800,                           //固定表格的高度
        classes:'table table-bordered table-hover',//表的类名。可以使用'table','table-bordered','table-hover','table-striped','table-dark','table-sm'和'table-borderless'。默认情况下,表格是有界的。
        theadClasses:'',// 表thead的类名 如使用.thead-light或.thead-dark使theads显示为浅灰色或深灰色。   
        rowStyle:function(row,index){},//    行样式格式化程序函数支持类或css
        rowAttributes:function(row,index){},//  row属性formatter函数,支持所有自定义属性  
        undefinedText:'-',// 定义默认的未定义文本   
        sortClass:'',//已排序的td元素的类名       
        rememberOrder:false,//设置为true以记住每列的顺序    
        data:[],//    要加载的数据 [] or {}
        contentType:'application/json',//请求远程数据的contentType,例如:application/x-www-form-urlencoded。    
        dataType:'json',//您希望服务器返回的数据类型    
        totalField:'total',//Key in incoming json containing 'total' data.
        dataField:'rows',//名称写自己定义的每列的字段名,也就是key,通过key才能给某行的某列赋value原文:获取每行数据json内的key
        onlyInfoPagination:false,//设置为true以仅显示表中显示的数据量。它需要将分页表选项即pagination设置为true    
        paginationLoop:true,//设置为true以启用分页连续循环模式    
        paginationHAlign:'right',//分页条水平方向的位置,默认right(最右),可选left   
        totalRows:0,//该属性主要由分页服务器传递,易于使用    
        paginationDetailHAlign:'left',//如果解译的话太长,举个例子,paginationDetail就是“显示第 1 到第 8 条记录,总共 15 条记录 每页显示 8 条记录”,默认left(最左),可选right    
        paginationVAlign:'bottom',//分页条垂直方向的位置,默认bottom(底部),可选top、both(顶部和底部均有分页条)    
        paginationPreText:'<',//上一页的按钮符号    
        paginationNextText:'>',//下一页的按钮符号    
        paginationSuccessivelySize:5,//分页时会有<12345...80>这种格式而5则表示显示...左边的的页数   
        paginationPagesBySide:1,//...右边的最大连续页数如改为2则 <1 2 3 4....79 80>   
        paginationUseIntermediate:false,//计算并显示中间页面以便快速访问 true 会将...替换为计算的中间页数42    
        searchOnEnterKey:false,// true时搜索方法将一直执行,直到按下Enter键(即按下回车键才进行搜索)   
        trimOnSearch:true,//默认true,自动忽略空格        
        searchAlign:'right',//指定搜索输入框的方向。可以使用'left','right'。    
        searchTimeOut:500,//设置搜索触发超时    
        searchText:'',//设置搜索文本框的默认搜索值  
        showHeader:true,//设置为false以隐藏表头    
        showFooter:false,//设置为true以显示摘要页脚行(固定也交 比如显示总数什么的最合适)    
        showPaginationSwitch:false,//设置为true以显示分页组件的切换按钮    
        showFullscreen:false,// 设置为true以显示全屏按钮   
        smartDisplay:true,//设置为true以巧妙地显示分页或卡片视图    
        escape:false,// 转义字符串以插入HTML,替换 &, <, >, “, `, 和 ‘字符  跳过插入HTML中的字符串,替换掉特殊字符 
        selectItemName:'btSelectItem',//  设置radio 或者 checkbox的字段名称   
        clickToSelect:false,//设置为true时 在点击列时可以选择checkbox或radio
        singleSelect:false,// 默认false,设为true则允许复选框仅选择一行(不能多选了?)
        checkboxHeader:true,//设置为false以隐藏标题行中的check-all复选框 即隐藏全选框     
        maintainSelected:false,// true时点击分页按钮或搜索按钮时,记住checkbox的选择项    设为true则保持被选的那一行的状态
        icons:{//定义工具栏,分页和详细信息视图中使用的图标    
            paginationSwitchDown: 'fa-caret-square-down',
            paginationSwitchUp: 'fa-caret-square-up',
            refresh: 'fa-sync',
            toggleOff: 'fa-toggle-off',
            toggleOn: 'fa-toggle-on',
            columns: 'fa-th-list',
            detailOpen: 'fa-plus',
            detailClose: 'fa-minus',
            fullscreen: 'fa-arrows-alt'
        },
        iconSize:'undefined',// 定义icon图表的尺寸大小html对应为data-icon-undefined (默认btn)、data-icon-lg 大按钮的尺寸(btn-lg)...;  这里的值依次为undefined => btnxs => btn-xssm => btn-smlg => btn-lg   
        iconsPrefix:'fa',//定义图标集名称(FontAwesome的'glyphicon'或'fa')。默认情况下,'fa'用于Bootstrap v4    
       
        queryParamsType:'limit',//设置'limit'以使用RESTFul类型发送查询参数。    
        ajaxOptions:{},//提交ajax请求的其他选项。值列表:jQuery.ajax。    
        customSort:function(sortName,sortOrder,data){},//自定义排序功能(用来代替自带的排序功能),需要两个参数(可以参考前面):    
        ajax:function(){},// 一种替换ajax调用的方法。应该实现与jQuery ajax方法相同的API       
        queryParams: function(params) { // 请求远程数据时,您可以通过修改queryParams来发送其他参数
            return params 
        },   
        responseHandler:function(res) { //在加载远程数据之前,处理响应数据格式,参数对象包含 
            return res 
        },   
        customSearch:function(data,text){// 执行自定义搜索功能替换内置搜索功能,需要两个参数   
            return data.filter(function (row) {return row.field.indexOf(text) > -1})
        },
        footerStyle:function(column){//  页脚样式格式化程序函数,只需一个参数 m默认{}  
            return {
                css: { 'font-weight': 'normal' }, 
                classes: 'my-class'
            }
        },
        detailFormatter:function(index,row,element){//前提:detailView设为true,启用了显示detail view。- 用于格式化细节视图- 返回一个字符串,通过第三个参数element直接添加到细节视图的cell(某一格)中,其中,element为目标cell的jQuery element    
            return '';
        },    detailFilter:function(index,row){//当detailView设置为true时,每行启用扩展。返回true并且将启用该行以进行扩展,返回false并禁用该行的扩展。默认函数返回true以启用所有行的扩展。    
            return true
        },    ignoreClickToSelectOn:function(element){// 包含一个参数:element: 点击的元素。返回 true 是点击事件会被忽略,返回 false 将会自动选中。该选项只有在 clickToSelect 为 true 时才生效。  
            return $.inArray(element.tagName, ['A', 'BUTTON']
        },   
       
        columns: [
            {checkbox: false},
            {radio: false},
            {
                radio: false,//此列转成radio上面单独领出来是应为有字段显示就不需要它呀
                checkbox: false,//此列转成checkbox  单独拎出来同上
                field: 'operate', //设置data-field的值
                title: __('Operate'),//设置data-field的值
                table: table,
                events: Table.api.events.operate,
                formatter: Table.api.formatter.operate,//单元格格式函数 this上下文是当前列对象
                formatter: function (value, row, index,field){},
                titleTooltip:'列标题工具提示文本。此选项还支持标题HTML属性',
                class:'定义列的类名',
                rowspan:1,//指定单元格应占用的行数。
                colspan:1,//指定单元格应占用的列数。
                align:'center',//指定如何对齐列数据。可以使用'left','right','center'。
                halign:'center',//指定如何对齐表头。可以使用'left','right','center'。
                falign:'center',//指示如何对齐表格页脚。可以使用'left','right','center'。
                valign:'middle',//指出如何对齐单元格数据。可以使用'top','middle','bottom'
                '10%',//列的宽度。如果未定义,宽度将自动扩展以适合其内容。格式'100px','10%',100,如果想表格保持列自适应并且尺寸太小,则可以忽略这项(通过类等使用min / max-width)
                sortable:false,//设置为true以允许列可以排序。
                order:'asc',//默认排序顺序,只能是'asc'或'desc'。
                visible:true,//设置为false以隐藏列项。
                cardVisible:true,//设置为false以隐藏card 视图状态中的列项
                switchable:true,//设置为false以禁用可切换的列项
                clickToSelect:true,//设置为true时 在点击列时可以选择checkbox或radio
                footerFormatter:function(data){},//当前列对象函数该函数应返回一个字符串,其中包含要在页脚单元格中显示的文本
                events::{},//使用格式化函数时的单元事件监听器 四个参数event,value,row,index; html可以这么用 <th .. data-events="operateEvent">
                sorter:function(a,b,rowA,rowB){},//用于进行本地排序的自定义字段排序函数(第一个字段值,第二个字段值,第一行,第二行)
                sortName:'',//提供可自定义的排序名称,而不是标题中的默认排序名称或列的字段名称
                cellStyle:function(value,row,index,field){},//单元格样式格式化函数 支持classs和css
                searchable:true,//设置为true以搜索此列的数据。
                searchFormatter:true,//设置为true以搜索使用格式化数据
                escape:false,//转义字符串以插入HTML,替换 &, <, >, “, `, and ‘ 字符。
                showSelectTitle:false,//设置为true以使用'radio'或'singleSelect''复选框'选项显示列的标题。
            }
    
        ]
    });
    var operateEvents = {
        /* 'click .like' 是类名?*/
        'click .like': function (e, value, row, index) {}
    }

    bootstrapTable   

    bootstraptable文档2

    中文文档

    模态框

    require.js

    require.js作为基本的js来启动所有的js  data-main属性指向了一个启动脚本加载过程的文件(一般和require文件同目录) 

    <script src="/assets/js/require.js" data-main="/assets/js/require-backend.js?v=1551577968"></script>

    然后在 data-main指向的js文件中定义模板加载选项  注意data-main里定义加载的文件是异步的哦,如果用了require.js那么就不要在之外定义对require.js里加载的文件有依赖的js

    require使用分两步;   基本的require例子

    1、define()定义模块(必须返回个对象)

    2、调用模块  require(function(){}) 

    //全局配置
    require.config({
        // 根路径设置,paths下面全部都是根据baseUrl的路径去设置
        baseUrl:'./js/',//显式的定义baseUrl;不显式定义的情况下默认是和require.js同一个目录如果定义了data-main则以data-main的路径(path以/开头、以.js结尾、含有https等协议时不会使用baseUrl?)
        
        paths:{//显式的映射哪些不是在baseUrl目录路径的文件
                // 引入jQuery.js
               jquery:'plugin/jquery',
               // 引入bootstrap.js
               bootstrap:'plugin/bootstrap',
               //引入其他的js
               //custom:'cunstom'
        },
        shim:{//为那些没有使用define()来声明依赖关系 想要实际加载指或者涉及的模块仍然需要一个常规的require、define调用,设置shim本身不会触发代码的加载
            bootstrap:{
                //deps定义依赖的,这里的bootstrap依赖jquery
                deps:["jquery"],
                exports:'该依赖没有加载成功输出这段'或者这里也可以是个函数                
            }
        },
         //map 对于给定的模块前缀,使用一个不同的模块ID来加载该模块  
          该特性仅适用于那些调用了define()并将其注册为匿名模块的真正AMD模块脚本。并且,请在map配置中仅使用绝对模块ID,“../some/thing”之类的相对ID不能工作。
    
          另外在map中支持“*”,意思是“对于所有的模块加载,使用本map配置”。如果还有更细化的map配置,会优先于“*”配置
    
         //当“some/newmodule”调用了“require('foo')”,它将获取到foo1.2.js
         //而当“some/oldmodule”调用“`require('foo')”时它将获取到foo1.0.js。
         //当调用其它时将获取到fool1.1.js
         foo1.0.js
         foo1.1.js
         foo1.2.js
         some/
             newmodule.js
             oldmodule.js
    
        map: {
            '*': {
                'foo': 'foo1.1'
            },
            'some/oldmodule': {
                'foo': 'foo1.2'
            },
            'some/oldmodule': {
                'foo': 'foo1.0'
            }
        }
    
    });

    urlArgs:RequireJS获取资源时附加在URL后面的额外的query参数。作为浏览器或服务器未正确配置时的“cache bust”手段很有用。使用cache bust配置的一个示例:

    urlArgs: "bust=" +  (new Date()).getTime()

    packages:从CommonJS包(package)中加载模块。参见从包中加载模块。

    include:xx

    paths:xx

    shim:xx

    baseUrl:xx

    map:xx

    waitSeconds:命名一个加载上下文。这允许require.js在同一页面上加载模块的多个版本,如果每个顶层require调用都指定了一个唯一的上下文字符串。想要正确地使用,请参考多版本支持一节

    charset:xx

    config:常常需要将配置信息传给一个模块。这些配置往往是application级别的信息,需要一个手段将它们向下传递给模块。在RequireJS中,基于requirejs.config()的config配置项来实现。要获取这些信息的模块可以加载特殊的依赖“module”,并调用module.config()

    nodeIdCompat: 在放弃加载一个脚本之前等待的秒数。设为0禁用等待超时。默认为7秒。

    context: 指定要加载的一个依赖数组。当将require设置为一个config object在加载require.js之前使用时很有用。一旦require.js被定义,这些依赖就已加载。使用deps就像调用require([]),但它在loader处理配置完毕之后就立即生效。它并不阻塞其他的require()调用,它仅是指定某些模块作为config块的一部分而异步加载的手段而已。

    deps: 指定要加载的一个依赖数组。当将require设置为一个config object在加载require.js之前使用时很有用。一旦require.js被定义,这些依赖就已加载。使用deps就像调用require([]),但它在loader处理配置完毕之后就立即生效。它并不阻塞其他的require()调用,它仅是指定某些模块作为config块的一部分而异步加载的手段而已。

    callback: 在deps加载完毕后执行的函数。当将require设置为一个config object在加载require.js之前使用时很有用,其作为配置的deps数组加载完毕后为require指定的函数。

    enforceDefine: 如果设置为true,则当一个脚本不是通过define()定义且不具备可供检查的shim导出字串值时,就会抛出错误。参考在IE中捕获加载错误一节。

    xhtml: 如果设置为true,则使用document.createElementNS()去创建script元素。

    使用:

    1、

    require(
        ['jquery', 'bootstrap'], 
        function ($, undefined) {
               
        }
    );

    2、定义模块:具有作用域来避免全局名称空间污染

    简单定义:

    define({
        color: "black",
        size: "unisize"
    });

    函数式定义:

    define(function () {
        //Do setup work here
    
        return {
            color: "black",
            size: "unisize"
        }
    });

    存在依赖的函数式定义:

    模块函数以参数"cart"及"inventory"使用这两个以"./cart"及"./inventory"名称指定的模块。在这两个模块加载完毕之前,模块函数不会被调用。

    严重不鼓励模块定义全局变量。遵循此处的定义模式,可以使得同一模块的不同版本并存于同一个页面上(参见 高级用法 )。另外,函参的顺序应与依赖顺序保存一致。

    返回的object定义了"my/shirt"模块。这种定义模式下,"my/shirt"不作为一个全局变量而存在。

    // my/shirt.js现在有一些依赖项,cart和inventory
    // 假设他们与shirt.js在同一目录中的模块
    define(["./cart", "./inventory"], function(cart, inventory) {
            //返回一个对象来定义"my/shirt"模块。
            return {
                color: "blue",
                size: "large",
                addToCart: function() {
                    inventory.decrement(this);
                    cart.add(this);
                }
            }
        }
    );

    将模块定义为一个函数

    // foo/title.js中的模块定义。 它使用之前的my/cart 和my/inventory模块,
    //但由于foo/title.js与"my" 模块位于不同的目录中,因此它使用模块依赖项名称中的"my" 来查找它们。 
    //名称的"my" 部分可以映射到任何目录,但默认情况下,它被假定相邻"foo"目录。
    define(["my/cart", "my/inventory"],
        function(cart, inventory) {
            //返回一个函数用来定义"foo/title".
            //它获取或者设置 window title.
            return function(title) {
                return title ? (window.title = title) :
                       inventory.storeName + ' ' + cart.name;
            }
        }
    );

    定义一个命名模块

    这些常由优化工具生成。你也可以自己显式指定模块名称,但这使模块更不具备移植性——就是说若你将文件移动到其他目录下,你就得重命名。一般最好避免对模块硬编码,而是交给优化工具去生成。优化工具需要生成模块名以将多个模块打成一个包,加快到浏览器的载人速度。

        //明确地定义 "foo/title"模块:
        define("foo/title",
            ["my/cart", "my/inventory"],
            function(cart, inventory) {
                //Define foo/title object in here.
           }
        );

    当定义的模块依赖太多的模块时

    如:

    //如:
    define(
        ['dep1', 'dep2', 'dep3', 'dep4', 'dep5', 'dep6', 'dep7', 'dep8'],
        function(dep1,   dep2,   dep3,   dep4,   dep5,   dep6,   dep7,   dep8){
            ...
        }
    );
    
    //可以简化成这样
    define(
        function (require) {
            var dep1 = require('dep1'),
                dep2 = require('dep2'),
                dep3 = require('dep3'),
                dep4 = require('dep4'),
                dep5 = require('dep5'),
                dep6 = require('dep6'),
                dep7 = require('dep7'),
                dep8 = require('dep8');
    
                ...
        }
    
    });

    注意:

    一个文件一个模块

    为了能在define()内部使用require的调用可以将require作一个依赖注入到模块中

    生成与相对于模块的url

    实例:

    文件:

    <script src="./require.js" data-main="main.js" type="text/javascript" defer async="true"></script>    

    全局配置文件main.js:

     /*全局配置*/
     require.config({
         baseUrl:'./',
         paths:{
             layer:"plugin/layer",
             jquery:["https://cdn.bootcss.com/jquery/3.3.1/jquery","plugin/jquery"],//可配置多个地址第一个加载不上加载第二个
             bootstrap:"https://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min",
             custom1:"js/custom1.0",
             custom2:"js/custom1.2",//custom1.2.js
             math:"js/math",//math.js
             datatable:"datatable",//和baseUrl同一文件下无需在这指定都行(可省略)
         },
         shim:{
             'datatable':{//这个键名为要是载入的目标文件的文件名,不能随便命名。
                 exports: '_' //exports的值为datatable.js提供的 对外接口的名称??不理解  在其他模块require引入时可以引用它
             },
             'datatables':{
                 'init':function(){
                     return{
              sayHi: datatable,//键可以随便取名(定义数据的键),值必须和datatables.js里的变量名一致
              sayHello: datatableDemo,
              sayname: name,
              sayLike: like,
                     }
                 },
                 'deps':['jquery','bootstrap'],//设置的依赖只datatable在jquery和bootstrap加载完毕后才会加载
                 //如果木有init这些参数我们可以简化依赖设置 例如 'datatables':['jquery','bootstrap'] 
                 //z注意bootstrap是依赖jqury的所以下面必须填上'bootstrap':['jquery'],
             },
             'layui':{
    
             },
             'bootstrap':['jquery'],
    
         }
    
     });
    
    require(['math'], function (math){
        //math:为math.js return回来的数据 {add: ƒ, mathAdd: ƒ, controller: {…}}
        console.log(math.add('1   ',1));
        console.log(math.controller);
    });

    模块文件math.js

    //不依赖其他模块
    //define(function (){
    //define([],function (){
    //依赖其他模块则第一个参数为数组值为依赖的模块(这里依赖jquey和layui还有datatable),
    //jqury和layui在main.js显式指定了位置,datatable.js没有在paths里没有指定那么他的路径会默认在baseUrl
    define(['jquery','layer','datatable','datatables'],function ($,layer,_,tables){    
        var mathAdd = function (x,y){
        
            console.log(datatable);//这里得到datatable是undefined,非规范化的模块我们需要定义在shim中
            console.log(_);//??
            console.log(tables);
    
    
            return parseInt($.trim(x))+parseInt($.trim(y));
        };
        var updateData=function(){
            return '需要的代码';
        };
    
        var controller={
            sex:'男',
            params:{
                id:'1',
                name:'tom',
                phone:13132613871
            },
            index:function(){
    
            },
            add:updateData,
            eidt:function(){
    
            }
        };
    
        return {
            add: mathAdd,
            mathAdd: mathAdd,
            controller:controller
        };
    });

    非规范化模块

    datatable。js

    var datatable={
    
        showRow:function(index){
            return idnex;
        }
    };

    datatable。js

    /*非规范的模块有许多变量对象等情况*/
    var datatable={
    
        showRow:function(index){
            return idnex;
        }
    };
    
    function datatableDemo(){
        return 'demo';
    }
    var name='tom';
    var like=['sing','jump','drink'];

    生成的模板  两表字段 id、name、category_id(关联的多的字段)

    add.html

    <form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
    
        <div class="form-group">
            <label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
            <div class="col-xs-12 col-sm-8">
                <input id="c-name" data-rule="required" class="form-control" name="row[name]" type="text">
            </div>
        </div>
        <div class="form-group layer-footer">
            <label class="control-label col-xs-12 col-sm-2"></label>
            <div class="col-xs-12 col-sm-8">
                <button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button><!--确定-->
                <button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button><!--重置-->
            </div>
        </div>
    </form>

    index:

    <div class="panel panel-default panel-intro">
        {:build_heading()}
    
        <div class="panel-body">
            <div id="myTabContent" class="tab-content">
                <div class="tab-pane fade active in" id="one">
                    <div class="widget-body no-padding">
                        <div id="toolbar" class="toolbar">
                            <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
                            <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('demo/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
                            <a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('demo/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
                            <a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('demo/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
                            <a href="javascript:;" class="btn btn-danger btn-import {:$auth->check('demo/import')?'':'hide'}" title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i> {:__('Import')}</a>
    
                            <div class="dropdown btn-group {:$auth->check('demo/multi')?'':'hide'}">
                                <a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
                                <ul class="dropdown-menu text-left" role="menu">
                                    <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=normal"><i class="fa fa-eye"></i> {:__('Set to normal')}</a></li>
                                    <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=hidden"><i class="fa fa-eye-slash"></i> {:__('Set to hidden')}</a></li>
                                </ul>
                            </div>
                        </div>
                        <table id="table" class="table table-striped table-bordered table-hover table-nowrap"
                               data-operate-edit="{:$auth->check('demo/edit')}" 
                               data-operate-del="{:$auth->check('demo/del')}" 
                               width="100%">
                        </table>
                    </div>
                </div>
    
            </div>
        </div>
    </div>

    edit.html

    <form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
    
        <div class="form-group">
            <label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
            <div class="col-xs-12 col-sm-8">
                <input id="c-name" data-rule="required" class="form-control" name="row[name]" type="text" value="{$row.name}">
            </div>
        </div>
        <div class="form-group layer-footer">
            <label class="control-label col-xs-12 col-sm-2"></label>
            <div class="col-xs-12 col-sm-8">
                <button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
                <button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
            </div>
        </div>
    </form>

    关联后的模板

    add

    <form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
    
        <div class="form-group">
            <label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
            <div class="col-xs-12 col-sm-8">
                <input id="c-name" data-rule="required" class="form-control" name="row[name]" type="text">
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-xs-12 col-sm-2">{:__('Category_id')}:</label>
            <div class="col-xs-12 col-sm-8">
                <input id="c-category_id" data-rule="required" data-source="category/selectpage" data-params='{"custom[type]":"dash"}' class="form-control selectpage" name="row[category_id]" type="text" value="">
            </div>
        </div>
        <div class="form-group layer-footer">
            <label class="control-label col-xs-12 col-sm-2"></label>
            <div class="col-xs-12 col-sm-8">
                <button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
                <button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
            </div>
        </div>
    </form>

    index:

    <div class="panel panel-default panel-intro">
        {:build_heading()}
    
        <div class="panel-body">
            <div id="myTabContent" class="tab-content">
                <div class="tab-pane fade active in" id="one">
                    <div class="widget-body no-padding">
                        <div id="toolbar" class="toolbar">
                            <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
                            <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('dash/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
                            <a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('dash/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
                            <a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('dash/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
                            <a href="javascript:;" class="btn btn-danger btn-import {:$auth->check('dash/import')?'':'hide'}" title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i> {:__('Import')}</a>
    
                            <div class="dropdown btn-group {:$auth->check('dash/multi')?'':'hide'}">
                                <a class="btn btn-primary btn-more dropdown-toggle btn-disabled disabled" data-toggle="dropdown"><i class="fa fa-cog"></i> {:__('More')}</a>
                                <ul class="dropdown-menu text-left" role="menu">
                                    <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=normal"><i class="fa fa-eye"></i> {:__('Set to normal')}</a></li>
                                    <li><a class="btn btn-link btn-multi btn-disabled disabled" href="javascript:;" data-params="status=hidden"><i class="fa fa-eye-slash"></i> {:__('Set to hidden')}</a></li>
                                </ul>
                            </div>
                        </div>
                        <table id="table" class="table table-striped table-bordered table-hover table-nowrap"
                               data-operate-edit="{:$auth->check('dash/edit')}" 
                               data-operate-del="{:$auth->check('dash/del')}" 
                               width="100%">
                        </table>
                    </div>
                </div>
    
            </div>
        </div>
    </div>

    {:$auth->check('dash/add')?'':'hide'} 检查权限 无权限加hide类隐藏

    edit.html

    <form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
    
        <div class="form-group">
            <label class="control-label col-xs-12 col-sm-2">{:__('Name')}:</label>
            <div class="col-xs-12 col-sm-8">
                <input id="c-name" data-rule="required" class="form-control" name="row[name]" type="text" value="{$row.name}">
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-xs-12 col-sm-2">{:__('Category_id')}:</label>
            <div class="col-xs-12 col-sm-8">
                <input id="c-category_id" data-rule="required" data-source="category/selectpage" data-params='{"custom[type]":"dash"}' class="form-control selectpage" name="row[category_id]" type="text" value="{$row.category_id}">
            </div>
        </div>
        <div class="form-group layer-footer">
            <label class="control-label col-xs-12 col-sm-2"></label>
            <div class="col-xs-12 col-sm-8">
                <button type="submit" class="btn btn-success btn-embossed disabled">{:__('OK')}</button>
                <button type="reset" class="btn btn-default btn-embossed">{:__('Reset')}</button>
            </div>
        </div>
    </form>

     新增输出下拉列表的数据:

    在_initialize方法里分配查出来的管理组变量给模板

     

    edit模板

        <div class="form-group">
            <label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
            <div class="col-xs-12 col-sm-8">
                {:build_select('group[]', $groupdata, null, ['class'=>'form-control selectpicker', 'multiple'=>'', 'data-rule'=>'required'])}
            </div>
        </div>

    模板的函数解析出来为:

     echo build_select('group[]', $groupdata, null, ['class'=>'form-control selectpicker', 'multiple'=>'', 'data-rule'=>'required']);

    调用该函数生成一个下拉列表的html(第一个参数是name值,第二个参数是数组或者,分隔的字符串)

    <select class="form-control selectpicker" multiple="" name="group[]" tabindex="-98">
        <option value="1"> 超级管理组</option>
        <option value="2">&nbsp;├ 二级管理组</option>
        <option value="3">&nbsp;&nbsp;├ 三级管理组</option>
        <option value="5">&nbsp;&nbsp;└ 三级管理组2</option>
        <option value="4">&nbsp;└ 二级管理组2</option>
    </select>

    common.php

    if (!function_exists('build_select')) {
    
        /**
         * 生成下拉列表
         * @param string $name
         * @param mixed $options
         * @param mixed $selected
         * @param mixed $attr
         * @return string
         */
        function build_select($name, $options, $selected = [], $attr = [])
        {
            $options = is_array($options) ? $options : explode(',', $options);
            $selected = is_array($selected) ? $selected : explode(',', $selected);
            return Form::select($name, $options, $selected, $attr);
        }
    }
  • 相关阅读:
    11 改进版通过队列实现一个生产者消费者模型
    13 精进版SVIP版通过队列实现一个生产者消费者模型
    12 再次改进版通过队列实现一个生产者消费者模型
    31 进程
    join方法
    30 进程 线程
    进程传参方式和创建方式2
    设计模式 单例模式
    设计模式 抽象工厂模式
    设计模式 简单工厂模式
  • 原文地址:https://www.cnblogs.com/lichihua/p/10429606.html
Copyright © 2011-2022 走看看