任何一个MVC结构都有运用的套路,或许称为流程。了解这个套路是应用结构进行疾速开发的条件。假如要运用一个没有运用过的结构开发,最佳做一个增修改查程序来先摸透这个结构的套路。
以下是一个自定义结构的增修改查版别,这个范本做的数据处理略微杂乱,所以也比通常的增修改查要杂乱。这儿记载一下范文,用于将来备用。
结构首要进入view目录依据mod定位类,然后依据act调用视图办法,在这个办法中能够依照套路调用相对应的action,action再去调用相对应的model。(这儿的View实习即是控制器人物,不过命名为View,实习混淆了控制器和视图)。这儿的Action和Model实习都是MVC中的M,M归于事务逻辑,依据实习,M能够有多种完成方法,TableGateway的方法是最常见的,这儿的Action即是事务逻辑,Model即是TableGateway,Action需求和数据库交互时,需求调用TableGateway进行操作,这个方法通常要求数据表和TableGateway有一个对应联系,TableGateway只专心于和数据库的交互逻辑(也包括和第三方API交互)。具体来说,比如更新 和 刺进操作,控制器接纳数据,能够做一定的底子处理,提交给Action,Action做逻辑处理,调用Model更新或刺进数据,然后回来成果给控制器,控制器依据成果和视图交互。理论上,数据提交到Action是应当由控制器来负责的,可是实习上为了便利,通常在Action中直接接纳来自客户端的数据(比如$_GET $_POST),这个行动实习上严重破坏了Action层,使得Action很难或许底子无法重用,假如这么操作,还不如直接在控制器中完成,底子不需求绕个圈。
Action和Model都是MVC中的M,所以在控制器中运用Action和Model都是合理的。因为有些数据的获取,不一定非要通过Action,只有需求对数据进行加工处理时(事务逻辑)才需求通过Action,Model虽然应当专心于和数据库的交互逻辑,可是也能够参加一些其它的底子逻辑,特别是很简单的数据,底子不需求绕个圈通过Action来完成。由此可见,代码安排可能会引进紊乱。事务逻辑能够写在控制器中,也写在Action中,也写在Model中,看来,开发标准的问题是需求强制性要求才能够……
每个View类从BaseView继承:
<?php
class TitleView extends BaseView{
public function __construct(){
parent::__construct();
}
public function view_modify(){
$checked = (!empty($_POST['psites']) && is_array($_POST['psites']))?$_POST['psites']:array();
// 接收数据
$title = array(
'title'=>!empty($_POST['search'])?$_POST['search']:'',
'sites'=>$checked,
'erpCates'=>!empty($_POST['erpCates'])?$_POST['erpCates']:''
);
$freshMessage = '';
if(!empty($_REQUEST['id'])){
$id = $_REQUEST['id'];
// 判断$id是否存在
}else{
$freshMessage = '数据有误.';
}
// 调用Action
if(isset($_POST['type']) && ($_POST['type'] == 'modify')){
$modifyData = $title;
$modifyData['id'] = $id;
$modifyData['type'] = 'modify';
$success = A('title')->act_addAndModify($modifyData);
if($success){
$_SESSION["freshMessage"] = "标题成功编辑。";
header("Location:index.php?mod=title&act=list");
exit;
}else{
$freshMessage = "编辑失败。";
}
}
$this->smarty->assign("freshMessage",$freshMessage);
// 数据回显
$tree = A('erpCates')->getSimpleCates();
$this->smarty->assign('tree',$tree);
// 更新失败时数据回显 依据提交的数据处理
if(isset($_POST['type']) && ($_POST['type'] == 'modify')){
$title['id'] = $id;
$title = A('title')->act_reproduce($title);
}else{
$title = A('title')->act_reproduceFromModify($id);
}
$this->smarty->assign($title);
$this->smarty->display('title_modify.html');
}
public function view_add(){
$checked = (!empty($_POST['psites']) && is_array($_POST['psites']))?$_POST['psites']:array();
// 接收数据
$title = array(
'title'=>!empty($_POST['search'])?$_POST['search']:'',
'sites'=>$checked,
'erpCates'=>!empty($_POST['erpCates'])?$_POST['erpCates']:''
);
$freshMessage = '';
if(isset($_POST['type']) && ($_POST['type'] == 'add')){
$addData = $title;
$addData['type'] = 'add';
$success = A('title')->act_addAndModify($addData);
if($success){
$_SESSION["freshMessage"] = "标题成功添加。";
header("Location:index.php?mod=title&act=list");
exit;
}else{
$freshMessage = "添加失败。";
}
}
$this->smarty->assign("freshMessage",$freshMessage);
// 回显数据
$tree= A('erpCates')->getSimpleCates();
$this->smarty->assign('tree',$tree);
$title = A('title')->act_reproduce($title);
$this->smarty->assign('search',$title['title']);
$this->smarty->assign('platformSite', $title['sites']);
$this->smarty->assign('erpCates',$title['erpCates']);
$this->smarty->display('title_add.html');
}
// 列表
public function view_list(){
if(!empty($_SESSION["freshMessage"])){
$this->smarty->assign('freshMessage',$_SESSION["freshMessage"]);
unset($_SESSION["freshMessage"]);
}
$selectedCates = isset($_REQUEST['selectedCates'])?trim($_REQUEST['selectedCates']):'';
$cates = A('title')->act_searchCates($selectedCates);
$this->smarty->assign('cateList',$cates['searchCates']);
$this->smarty->assign('erpCates',$cates['erpCates']);
$selectedSite = isset($_REQUEST['sites'])?$_REQUEST['sites']:'';
$sites = A('title')->act_searchSites($selectedSite);
$this->smarty->assign('platformSiteView', $sites);
// 列表数据
$this->view_listShow();
$this->smarty->display('title_list.html');
}
// Ajax删除
public function view_delete(){
$this->view_delData();
}
}
对于一个列表,可以调用view_listShow(),内部会去调用对应的action的act_getDataList获取数据(一页),act_getDataCount获取总数量传递给一个分页类,最终注册到list和show_page变量(Smarty)。一个基本套路,对于更新和插入,都是先接收数据,然后判断是否应用更新插入,然后是处理回显数据。先接收的数据可以应用到插入和更新中去,也方便后面的数据回显,避免了多次组装数据,另外也方便抽象业务逻辑(不需要传递$_GET和$_POST这类变量)。由于提交的数据只是用户选中的数据,所以要根据选中的数据,经过处理后传递回到视图(比如一个下拉框,选中了某一个项,但是回显时需要把整个下拉框数据都带上,而且标记选中的项),更新和插入基本类似,插入回显的数据是根据客户提交的数据,而更新回显的数据有两个,第一次回显是保存在数据库中的数据,第二次回显是是客户端提交的数据。
注意:如果使用封装的方法,就必须在对应的Action中定义对应的方法(默认是不存在的):
<?php
class TitleAct extends CheckAct {
public function __construct(){
parent::__construct();
}
// 数据回显,修改时回送到客户端的数据
public function act_reproduceFromModify($id=''){
$title = M('title')->getSingleData("*"," `id`='".$id."' ");
return $this->act_reproduce($title);
}
// 数据回显
public function act_reproduce($title=array()){
$return = array(
'id'=>'',
'title'=>'',
'sites'=>array(),
'erpCates'=>array()
);
$return['id'] = isset($title['id'])?$title['id']:'';
$return['title'] = isset($title['title'])?$title['title']:'';
$checked = array();
if(isset($title['sites'])){
if(is_array($title['sites'])){
$checked = $title['sites'];
}else if(is_string($title['sites'])){
$checked = explode(',', $title['sites']);
}
}
$return['sites'] = $this->act_platformSites($checked);
$displayCates = array();
if(!empty($title['erpCates'])){
$cates = explode(',', $title['erpCates']);
foreach($cates as $cate){
$catee = explode('|',$cate);
if(isset($catee[0])){
$cateee = explode('-',$catee[0]);
if(is_array($cateee)){
$displayCates[] = array_pop($cateee);
}
}
}
}
$return['erpCates'] = json_encode($displayCates);
return $return;
}
// 回显到客户端的站点数据
public function act_platformSites($checked=array()){
$platform = M('platform')->fetchAll("SELECT * FROM platform");
$site = M('site')->fetchAll("SELECT * FROM site");
$platformSite = array();
$platformSite[0]['id'] = 0;
if(in_array('0|0',$checked)){
$platformSite[0]['checked'] = 1;
}else{
$platformSite[0]['checked'] = 0;
}
foreach($platform as $plt){
$platformSite[$plt['id']]['id'] = $plt['id'];
$platformSite[$plt['id']]['name'] = $plt['name'];
$platformSite[$plt['id']]['site'][0]['id'] = 0;
if(in_array($plt['id'].'|0',$checked)){
$platformSite[$plt['id']]['site'][0]['checked'] = 1;
}else{
$platformSite[$plt['id']]['site'][0]['checked'] = 0;
}
foreach($site as $s){
if($s['platform_id'] == $plt['id']){
$platformSite[$plt['id']]['site'][$s['id']]['id'] = $s['id'];
$platformSite[$plt['id']]['site'][$s['id']]['name'] = $s['name'];
if(in_array($plt['id'].'|'.$s['id'],$checked)){
$platformSite[$plt['id']]['site'][$s['id']]['checked'] = 1;
}else{
$platformSite[$plt['id']]['site'][$s['id']]['checked'] = 0;
}
}
}
}
return $platformSite;
}
// 搜索框目录数据
public function act_searchCates($selectedCates=''){
$erpCates = A('erpCates')->getSubCates();
$erpCatesArr = json_decode($erpCates,true);
$cateList = array();
if(empty($selectedCates)){
foreach($erpCatesArr[0] as $idx=>$vle){
$cateList[0][$vle['id']] = array('id'=>$vle['id'],'name'=>$vle['name'],'selected'=>0);
}
}else{
$cids = explode('-',$selectedCates);
$pid = 0;
$count = count($cids);
for($i = 0; $i < $count; $i++){
foreach($erpCatesArr[$pid] as $idx=>$vle){
$selected = 0;
if($vle['id'] == $cids[$i]){ $selected = 1; }
$cateList[$pid][$vle['id']] = array('id'=>$vle['id'],'name'=>$vle['name'],'selected'=>$selected);
}
$pid = $cids[$i];
}
}
return array('erpCates'=>$erpCates,'searchCates'=>$cateList);
}
// 搜索框站点数据
public function act_searchSites($selectedSite=''){
$platform = M('platform')->fetchAll("SELECT * FROM platform");
$site = M('site')->fetchAll("SELECT * FROM site");
$platformSiteView = array();
foreach($platform as $plt){
foreach($site as $s){
if($s['platform_id'] == $plt['id']){
$platformSiteView[$plt['id'].'|'.$s['id']] = $plt['name'].'/'.$s['name'];
}
}
}
return $platformSiteView;
}
// 数据列表
public function act_getDataList() {
$search = isset($_GET['search'])?trim($_GET['search']):'';
$sites = isset($_GET['sites'])?trim($_GET['sites']):'';
$selectedCates = isset($_GET['selectedCates'])?trim($_GET['selectedCates']):'';
$where = "is_delete='0' ";
if(!empty($search)){
$where .= " AND title like '%".mysql_real_escape_string($search)."%' ";
}
if(!empty($sites)){
$where .= " AND sites like '%".mysql_real_escape_string(trim($sites))."%' ";
}
if(!empty($selectedCates)){
$where .= " AND erpCates like '%".mysql_real_escape_string(trim($selectedCates))."%' ";
}
$data = M($this->act_getModel())->getData("*", $where, "ORDER BY id DESC", $this->page, $this->perpage);
$platform = M('platform')->fetchAll("SELECT * FROM platform");
$site = M('site')->fetchAll("SELECT * FROM site");
$allPlatform = array();
foreach($platform as $plt){
$allPlatform[$plt['id']] = $plt['name'];
}
$allSite = array();
foreach($site as $s){
$allSite[$s['platform_id']][$s['id']] = $s['name'];
}
foreach($data as $didx=>$d){
$sites = explode(',', $d['sites']);
$siteList = array();
foreach($sites as $site){
$spilt = explode('|',$site);
if(($spilt[0] == 0) || ($spilt[1] == 0)){ continue; }
if(isset($allSite[$spilt[0]][$spilt[1]])){
$siteList[$spilt[0]]['site'][] = $allSite[$spilt[0]][$spilt[1]];
}
}
$siteStr = '';
foreach($siteList as $piid=>$psite){
$siteStr .= $allPlatform[$piid]."|".implode(', ', $psite['site'])."<br />";
}
$data[$didx]['sites'] = $siteStr;
if(!empty($d['erpCates'])){
$displayCates = array();
$cates = explode(',', $d['erpCates']);
foreach($cates as $cate){
$catee = explode('|',$cate);
if(isset($catee[1])){
$displayCates[] = $catee[1];
}
}
$data[$didx]['erpCates'] = implode("<br />", $displayCates);
}
}
return $data;
}
// 总数量
public function act_getDataCount() {
$search = isset($_GET['search'])?trim($_GET['search']):'';
$sites = isset($_GET['sites'])?trim($_GET['sites']):'';
$where = "is_delete='0' ";
if(!empty($search)){
$where .= " AND title like '%".mysql_real_escape_string(trim($search))."%' ";
}
if(!empty($sites)){
$where .= " AND sites like '%".mysql_real_escape_string(trim($sites))."%' ";
}
$count = M($this->act_getModel())->getDataCount($where);
return $count;
}
// 删除一行
public function act_delData(){
$id = $_GET['id'];
$title = M($this->act_getModel())->deleteData($id);
return $title;
}
// 插入与修改
public function act_addAndModify($data){
$d = array(
'title' => $data['title'],
'sites' => implode(',',$data['sites']),
'erpCates' => $data['erpCates']
);
$success = false;
if($data['type'] == 'mofify'){
// 做合理性判断 比如是否标题重复...
$id = $data['id'];
$success = M('title')->updateData($id, $d);
}else{
$success = M('title')->insertData($d);
}
return $success;
}
}
业务逻辑应该是尽可能的可重用。act_getDataList和act_getDataCount决定了如何获取数据 和 数据集合的总大小。这两个方法是框架内置的默认方法,在控制器中调用$this->view_listShow()时使用到。
<?php
class TitleModel extends CommonModel{
public function __construct(){
parent::__construct();
}
}
模型的相关方法大多都已经封装好。不过需要定义一个is_delete字段,类似为整数,因为删除时,实际修改这个字段由0变成1。
最后是模板文件:
########################
##title_list.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<script src="js/jquery/jquery-1.8.3.js" type="text/javascript"></script>
<script type="text/javascript">
var mod = "{$mod}";
var act = "{$act}";
var erpCatess = {$erpCates}
{if $freshMessage neq ''}
alert("{$freshMessage}");
{/if}
{literal}
$(function(){
$(".deleteItem").click(function(){
if(confirm("确认删除吗?")){
var id = $(this).attr("id");
// {"errCode":200,"errMsg":"xxxx","data":true}
$.get('index.php',{"mod":mod,"act":"delete","id":id},function(d){
if(d.data){
alert("成功删除...");
$("#searchForm").submit();
}
});
}
return false;
});
$(document).on('change','.erpCate',function(){
var catePath = $(this).val();
catePath = catePath.split('-');
var cid = catePath.pop();
selectHtml(cid,$(this));
});
$("#searchForm").submit(function(){
var cids = [];
$("#catesCon select").each(function(){
cids.push($(this).val());
});
$("#selectedCates").val(cids.join('-'));
});
});
function selectHtml(pid,e){
var selectHtml = '';
if(pid == ''){
e.nextAll('.erpCate').remove();
return false;
}
erpCates = erpCatess[pid];
if(!erpCates){
e.nextAll('.erpCate').remove();
return false;
}
for(var i=0;i<erpCates.length;i++){
selectHtml += "<option value='"+erpCates[i].id+"' idV='"+erpCates[i].id+"'>"+erpCates[i].name+"</option>";
}
$('.erpCate').attr('name','');
e.nextAll('.erpCate').remove();
e.after('<select name="erpCateId" class="select_cpfzr erpCate"><option value="">请选择</option>'+selectHtml+'</select>');
}
{/literal}
</script>
</head>
<body>
<form id="searchForm" name="" method="get" action="">
<input type="hidden" value="{$mod}" name="mod" />
<input type="hidden" value="{$act}" name="act" />
<input type="hidden" value="" name="selectedCates" id="selectedCates" />
<table>
<tr>
<td>标题:<input type="text" name="search" value="{$g_search}" /></td>
<td>
类目:
<span id="catesCon">
{foreach $cateList as $iid=>$cca}
<select class="erpCate">
<option value="">请选择</option>
{foreach $cca as $cidx=>$cvle}
<option value="{$cvle['id']}" {if $cvle['selected'] == 1}selected="selected"{/if}>{$cvle['name']}</option>
{/foreach}
</select>
{/foreach}
</span>
</td>
<td>平台站点:
<select name="sites">
<option value="">选择站点</option>
{foreach from=$platformSiteView key=k item=val}
<option value="{$k}"{if $g_sites == $k} selected="selected"{/if}>{$val}</option>
{/foreach}
</select>
</td>
<td>
<input type="submit" value="搜索" /> <a href="index.php?mod=title&act=add">添加</a>
</td>
</tr>
</table>
<table>
<tr>
<td style="width:100px;border-bottom:1px solid #ccc">序号</td>
<td style="width:300px;border-bottom:1px solid #ccc">标题</td>
<td style="width:300px;border-bottom:1px solid #ccc">子类目</td>
<td style="width:300px;border-bottom:1px solid #ccc">站点</td>
<td style="border-bottom:1px solid #ccc">操作</td>
</tr>
{if count($list) > 0}
{foreach from=$list key=ikey item=ival}
<tr>
<td style="border-bottom:1px solid #ccc;vertical-align:top">{$ikey+1}</td>
<td style="border-bottom:1px solid #ccc;vertical-align:top">{$ival['title']}</td>
<td style="border-bottom:1px solid #ccc;vertical-align:top">{$ival['erpCates']}</td>
<td style="border-bottom:1px solid #ccc;vertical-align:top">{$ival['sites']}</td>
<td style="border-bottom:1px solid #ccc;vertical-align:top"><a href="index.php?mod={$mod}&act=modify&id={$ival['id']}">编辑</a> -- <a id="{$ival['id']}" class="deleteItem" href="">删除</a></td>
</tr>
{/foreach}
{/if}
<tr>
<td colspan="4">{$show_page}</td>
</tr>
</table>
</form>
</body>
</html>
#############################
##title_add.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<script src="js/jquery/jquery-1.8.3.js" type="text/javascript"></script>
<script src="js/jquery.ztree.all-3.5.min.js"></script>
<link rel="stylesheet" href="css/zTreeStyle/zTreeStyle.css" type="text/css" media="all" />
<script type="text/javascript">
var mod = "{$mod}";
var act = "{$act}";
var treeJson = {$tree};
var displayCates = {$erpCates};
{if $freshMessage neq ''}
alert("{$freshMessage}");
{/if}
{literal}
var setting = {
view:{
// 双击展开
dblClickExpand: true,
// 是否显示对齐线
showLine: false,
// 是否显示图标
showIcon:false
},
data: {
simpleData: {
// 是否启用简单数据模式(这个方式只要把每个目录按照如下格式读出放入数组即可)
enable: true,
// 目录ID的标识符
idKey: "id",
// 符目录ID标识符
pIdKey: "parentid",
// 根目录ID值
rootPId: 0
}
},
check: {
// 是否启用选框
enable: true,
// 设置自动关联勾选时是否触发 beforeCheck / onCheck 事件回调函数
autoCheckTrigger: true,
chkStyle: "checkbox"
}
};
$(function(){
zTree = $.fn.zTree.init($("#erpTree"), setting, treeJson);
if(displayCates !== undefined){
for(i in displayCates){
// 获取节点对象
var node = zTree.getNodeByParam('id',displayCates[i]);
// 选中节点 第一参数必须是zTree内部节点对象,第二参数表示是否选中,第三参数表示是否联动操作(子节点选中,父节点也选上)
zTree.checkNode(node, true, true);
// 更新节点信息
//zTree.updateNode(node);
}
}
$(".line input").click(function(){
var checked = $(this).prop('checked');
if($(this).val() == '0|0'){
$(this).parents("ul").siblings().find("input").prop('checked',checked);
}else{
$(this).parents("ul").find("li.sub input").prop('checked',checked);
}
});
$("#searchForm").submit(function(){
//$("#testss").click(function(){
// 获取所有选中的节点对象
var checkedNodes = zTree.getCheckedNodes(true);
// 选中节点ID与对象对照表
var cates = {};
for(var ii in checkedNodes){
cates[checkedNodes[ii]['id']] = checkedNodes[ii];
}
// 子节点路径对应
var catePath = [];
for(i in checkedNodes){
// 子节点 回溯 获取路径
if(!checkedNodes[i]['isParent']){
var id = checkedNodes[i]['id'], name = checkedNodes[i]['name'];
var ids = [], names = [];
ids.push(id); names.push(name);
pid = checkedNodes[i]['parentid'];
for(var j=0; j<30; j++){
if(pid != 0){
node = cates[pid];
ids.push(node['id']);
names.push(node['name']);
pid = node['parentid'];
}else{
break;
}
}
catePath.push(ids.reverse().join('-')+"|"+names.reverse().join('-'));
}
}
//console.log(catePath.join(','));
$("#erpCates").val(catePath.join(','));
});
});
{/literal}
</script>
<style>
ul, li{
padding:0px;
margin:0px;
list-style:none;
}
ul{ clear:both; padding:15px 0px; width:300px;}
li.line{ border-bottom:1px solid #ccc;}
li{ padding:5px 0px;}
li.sub{ float:left; }
</style>
</head>
<body>
<form id="searchForm" name="" method="post" action="">
<input type="hidden" value="{$mod}" name="mod" />
<input type="hidden" value="{$act}" name="act" />
<input type="hidden" value="add" name="type" />
<input type="hidden" value="" id="erpCates" name="erpCates" />
<table>
<tr>
<td>
标题:<br />
<input type="text" name="search" value="{$search}" /></td>
</tr>
<tr>
<td>
类目:<br />
<div id="erpTree" class="ztree"></div>
</td>
</tr>
<tr>
<td>
站点:<br />
{foreach $platformSite as $idx=>$pval}
{if $idx == 0}
<ul>
<li class="line"><input name="psites[]" type="checkbox" value="0|0" {if $pval['checked'] == 1}checked="checked"{/if} />全选</li>
</ul>
{else}
<ul>
{foreach $pval['site'] as $pidx=>$pidv}
{if $pidx == 0}
<li class="line"><input name="psites[]" type="checkbox" value="{$idx}|0" {if $pidv['checked'] == 1}checked="checked"{/if} />{$pval['name']} -- 全选</li>
{else}
<li class="sub"><input name="psites[]" type="checkbox" value="{$idx}|{$pidx}" {if $pidv['checked'] == 1}checked="checked"{/if} />{$pidv['name']}</li>
{/if}
{/foreach}
</ul>
{/if}
{/foreach}
</td>
</tr>
<tr>
<td>
<input type="submit" value="添加" />
</td>
</tr>
</table>
</form>
</body>
</html>
###############################
##title_modify.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<script src="js/jquery/jquery-1.8.3.js" type="text/javascript"></script>
<script src="js/jquery.ztree.all-3.5.min.js"></script>
<link rel="stylesheet" href="css/zTreeStyle/zTreeStyle.css" type="text/css" media="all" />
<script type="text/javascript">
var mod = "{$mod}";
var act = "{$act}";
var treeJson = {$tree};
var displayCates = {$erpCates};
{if $freshMessage neq ''}
alert("{$freshMessage}");
{/if}
{literal}
var setting = {
view:{
// 双击展开
dblClickExpand: true,
// 是否显示对齐线
showLine: false,
// 是否显示图标
showIcon:false
},
data: {
simpleData: {
// 是否启用简单数据模式(这个方式只要把每个目录按照如下格式读出放入数组即可)
enable: true,
// 目录ID的标识符
idKey: "id",
// 符目录ID标识符
pIdKey: "parentid",
// 根目录ID值
rootPId: 0
}
},
check: {
// 是否启用选框
enable: true,
// 设置自动关联勾选时是否触发 beforeCheck / onCheck 事件回调函数
autoCheckTrigger: true,
chkStyle: "checkbox"
}
};
$(function(){
zTree = $.fn.zTree.init($("#erpTree"), setting, treeJson);
if(displayCates !== undefined){
for(i in displayCates){
// 获取节点对象
var node = zTree.getNodeByParam('id',displayCates[i]);
// 选中节点 第一参数必须是zTree内部节点对象,第二参数表示是否选中,第三参数表示是否联动操作(子节点选中,父节点也选上)
zTree.checkNode(node, true, true);
// 更新节点信息
//zTree.updateNode(node);
}
}
$(".line input").click(function(){
var checked = $(this).prop('checked');
if($(this).val() == '0|0'){
$(this).parents("ul").siblings().find("input").prop('checked',checked);
}else{
$(this).parents("ul").find("li.sub input").prop('checked',checked);
}
});
$("#searchForm").submit(function(){
//$("#testss").click(function(){
// 获取所有选中的节点对象
var checkedNodes = zTree.getCheckedNodes(true);
// 选中节点ID与对象对照表
var cates = {};
for(var ii in checkedNodes){
cates[checkedNodes[ii]['id']] = checkedNodes[ii];
}
// 子节点路径对应
var catePath = [];
for(i in checkedNodes){
// 子节点 回溯 获取路径
if(!checkedNodes[i]['isParent']){
var id = checkedNodes[i]['id'], name = checkedNodes[i]['name'];
var ids = [], names = [];
ids.push(id); names.push(name);
pid = checkedNodes[i]['parentid'];
for(var j=0; j<30; j++){
if(pid != 0){
node = cates[pid];
ids.push(node['id']);
names.push(node['name']);
pid = node['parentid'];
}else{
break;
}
}
catePath.push(ids.reverse().join('-')+"|"+names.reverse().join('-'));
}
}
//console.log(catePath.join(','));
$("#erpCates").val(catePath.join(','));
});
});
{/literal}
</script>
<style>
ul, li{
padding:0px;
margin:0px;
list-style:none;
}
ul{ clear:both; padding:15px 0px; width:300px;}
li.line{ border-bottom:1px solid #ccc;}
li{ padding:5px 0px;}
li.sub{ float:left; }
</style>
</head>
<body>
<form id="searchForm" name="" method="post" action="">
<input type="hidden" value="{$mod}" name="mod" />
<input type="hidden" value="{$act}" name="act" />
<input type="hidden" value="modify" name="type" />
<input type="hidden" value="{$id}" name="id" />
<input type="hidden" value="" id="erpCates" name="erpCates" />
<table>
<tr>
<td><input type="text" name="search" value="{$title}" /></td>
</tr>
<tr>
<td>
类目:<br />
<div id="erpTree" class="ztree"></div>
</td>
</tr>
<tr>
<td>
{foreach $sites as $idx=>$pval}
{if $idx == 0}
<ul>
<li class="line"><input name="psites[]" type="checkbox" value="0|0" {if $pval['checked'] == 1}checked="checked"{/if} />全选</li>
</ul>
{else}
<ul>
{foreach $pval['site'] as $pidx=>$pidv}
{if $pidx == 0}
<li class="line"><input name="psites[]" type="checkbox" value="{$idx}|0" {if $pidv['checked'] == 1}checked="checked"{/if} />{$pval['name']} -- 全选</li>
{else}
<li class="sub"><input name="psites[]" type="checkbox" value="{$idx}|{$pidx}" {if $pidv['checked'] == 1}checked="checked"{/if} />{$pidv['name']}</li>
{/if}
{/foreach}
</ul>
{/if}
{/foreach}
</td>
</tr>
<tr>
<td>
<input type="submit" value="修改" />
</td>
</tr>
</table>
</form>
</body>
</html>
这里需要注意的是,GET 和 POST过去的数据,对应g_xxx和p_xxx这样的形式返回到模板,可以使用它们填充表单,不过面对复杂数据时(比如单选 和 多选,还是自己处理为好,参考以上的数据回显)。
BaseView中定义了view_updateData,view_addData,view_delData,view_getSingleData对应了Action的同名方法(需要自定义),在这些方法中接收参数,调用Model处理数据,数据返回到View方法中,在View方法中再次对这个结果进行JSON封装输出,参考以上的示例,这个是为Ajax方法的交互做准备的。
(责任编辑:最模板) |