2021SC@SDUSC
本周我们来解析cmswing文件夹下最后一个核心文件:modindexbase.js。
1.
async __before() {
await super.__before();
const getCategory = this.get('category') ? this.get('category').split('-')[0].slice(1) : false;
if (this.get('category') || this.get('cid')) {
this.m_cate = await this.category(getCategory || this.get('cid'));
this.mod = await this.model('cmswing/model').get_model(this.m_cate.model);
if (think.isEmpty(this.mod)) {
const error = this.controller('cmswing/error');
return error.noAction('模型不存在或被禁用!');
}
this.meta_title = this.m_cate.meta_title ? this.m_cate.meta_title : this.m_cate.title;
this.keywords = this.m_cate.keywords ? this.m_cate.keywords : '';
this.description = this.m_cate.description ? this.m_cate.description : '';
}
}
modindexbase.js中的__before()与modadminbase.js的__before()一样,规定了模型公共参数,继承了父类__before(admin.js中),执行验证登录、用户信息等操作的代码,不同的是,modindexbase.js中的__before()在这之后是用了一个嵌套的if语句,通过this.category(getCategory || this.get('cid'))来获取当前模型栏目id,通过this.model('cmswing/model').get_model(this.m_cate.model)来获取当前模型信息,然后通过内部的if语句来判断this.mod方法的返回值是否为空,以此来判断当前模型是否存在或被禁用。
2.
async indexAction() {
try {
await this.action('mod/' + this.mod.name + '/index', 'index');
} catch (err) {
assert(!think.isError(err), err);
}
}
indexAction()与modadminbase.js中的相同,先判断判断方法是否有错,然后获取封面入口返回给前端。
3.
async listAction() {
try {
await this.action('mod/' + this.mod.name + '/index', 'list');
} catch (err) {
assert(!think.isError(err), err);
}
//
}
moderrorAction() {
return this.display('cmswing/moderror');
}
modDisplay(p = this.ctx.action, m = '') {
let c = this.ctx.controller.split('/');
if (this.ctx.controller === 'cmswing/route') {
c = `mod/${this.mod.name}/index`.split('/');
if (Number(this.m_cate.allow_publish) === 1 && p === 'index') {
p = 'list';
} else if (think.isEmpty(p)) {
p = 'index';
}
}
if (p === 'm' || !think.isEmpty(m)) {
if (p === 'm') {
p = this.ctx.action;
if (this.ctx.controller === 'cmswing/route') {
p = Number(this.m_cate.allow_publish) === 1 ? 'list' : 'index';
}
}
const pp = path.join(think.ROOT_PATH, 'src', 'controller', 'mod', c[1], 'view', 'mobile', c[2]);
return this.display(`${pp}_${p}`);
} else {
const pp = path.join(think.ROOT_PATH, 'src', 'controller', 'mod', c[1], 'view', 'pc', c[2]);
return this.display(`${pp}_${p}`);
}
}
async hookRender(p = this.ctx.action, mod = '', m = '') {
// console.log(this.ctx.controller);
if (p === 'm' || !think.isEmpty(m)) {
if (p === 'm') p = this.ctx.action;
const pp = path.join(think.ROOT_PATH, 'src', 'controller', 'mod', mod, 'view', 'mobile', 'hooks');
return await this.render(`${pp}_${p}`);
} else {
const pp = path.join(think.ROOT_PATH, 'src', 'controller', 'mod', mod, 'view', 'pc', 'hooks');
return await this.render(`${pp}_${p}`);
}
}
modget(n) {
const get = this.get('category') || 0;
const query = get.split('-');
return query[n];
}
listAction()、moderrorAction() 、modDisplay(p = this.ctx.action, m = '')、hookRender(p = this.ctx.action, mod = '', m = '')、modget(n)五个方法组合使用用来获取列表入口。
listAction()与indexAction()相似,先判断判断方法是否有错,然后获取封面入口返回给前端。
moderrorAction()方法负责创建独立模型时的错误提示,其主体是cmswing中的moderror方法,将moderror的返回值传给this.display(),若出错则给予提示。而modDisplay(p = this.ctx.action, m = '')则负责将独立模型display方法封装。
hookRender(p = this.ctx.action, mod = '', m = '')是获取模板方法(钩子方法)的方法。模板方法定义了操作中的算法骨架,将某些步骤掩饰到子类中实现,这样就可以在不改变和算法前提的情况下,重新定义该算法的某些特定步骤。
modget(n)通过独立模型get方法封装,只针对index入口action,其他的则使用 this.get()方法。
4.
async breadcrumb(cid = this.m_cate.id) {
const breadcrumb = await this.model('cmswing/category').get_parent_category(cid, true);
this.assign('breadcrumb', breadcrumb);
}
};
与modadminbase.js相同,breadcrumb()用来负责网页中面包屑的显示。面包屑它是一种线性的导航方式,是一种“历史记录”的应用方式,目的是帮助你追溯来路(在网页的应用中,“追溯来路”这件事浏览器已经很OK了)现在变成用来表达内容归属关系的界面元素。 我们经常看到的“主分类>一级分类>二级分类>三级分类>……>最终内容页面”这样的方式。一般正常的来讲目录结构由3层结构组成。分别是首页>栏目页>内容页。
使用面包屑,可以让用户了解目前所处位置,以及当前页面在整个网站中的位置。面包屑方便了用户,主要用于为用户提供导航一个网站的次要方法,通过为一个大型多级网站的所有页面提供面包屑路径,用户可以更容易的定位到上一次目录,引导用户通行,减少了返回到上一级页面的点击或操作,不用使用浏览器的“返回”按钮或网站的主要导航来返回到上一级页面。而且,面包屑不用常常占用屏幕空间,因为它们通常是水平排列以及简单的样式,面包屑路径不会占用页面太多的空间。这样的好处是,从内容过载方面来说,他们几乎没有任何负面影响。同时,面包屑降低了跳出率,面包屑路径会是一个诱惑首次访问者在进入一个页面后去浏览这个网站的非常好的方法。比如说,一个用户通过谷歌搜索到一个页面,然后看到一个面包屑路径,这将会诱使用户点击上一级页面去浏览感兴趣的相关主题,也体现了网站的架构层级,能够帮助用户快速学习和了解网站内容和组织方式,从而形成很好的位置感,有利于网站内链的建设,用面包屑大大增加了网站的内部连接,提高用户体验。
5.
async c_verify(ac, cid = this.m_cate.id, info = '您所在的用户组,禁止访问本栏目!') {
let roleid = 8;
if (this.is_login) {
roleid = await this.model('member').where({id: this.is_login}).getField('groupid', true);
}
const priv = await this.model('cmswing/category_priv').priv(cid, roleid, ac);
return priv;
}
c_verify()方法是负责前台用户组栏目权限验证的方法,visit代表访问验证权限,add代表投稿验证权限,edit代表前台编辑控制权限。若let变量roleid的值为8,则代表当前访问的是游客,返回提示:“您所在的用户组,禁止访问本栏目!”,然后通过if语句中的this.is_login控制访问,返回用户的权限。
6.
page_num() {
let num;
if (this.m_cate.list_row > 0) {
num = this.m_cate.list_row;
} else if (this.m_cate.model.split(',').length == 1) {
const pagenum = this.mod.list_row;
if (pagenum != 0) {
num = pagenum;
}
} else {
num = 10;
}
if (this.isMobile) {
num = 10;
}
return num;
}
page_num()方法用来记录当前栏目列表每页行数,先设置一个变量num,若每页行数大于0,则当前行数为num值,否则设置为10。最终num数即为行数值。