定好View

首先,根据页面切分View,切分View的规则是将重复利用的视图或者功能相近的视图归于一个View,对于Backbone,每一个model都要对应一个View。父层View负责布局,并将model发给子层View,让子层view负责渲染model数据。View并不是越多越好,要合理设计,View过多将会导致View资源管理成为负担;另外,View过于精简,可能会造成View的不必要的渲染工作。页面切分很有讲究,所以这一部分工作建议进行统一设计。

以下图作为例子进行View设计:

View设计如下:

这里一共有7个View(实际还有几个潜在view,比如弹窗,上传图片页面等,原理是一样的):

MyMainView负责全局布局,并将子View的渲染内容填充到页面中;

TopView负责渲染页面头,包括网站图标,工具栏,关于我们等;

ContentView负责渲染页面主要内容;

FooterView负责渲染页面底部信息,包括©copyright等;

ContentView 里面还可以继续划分:

ContentTopView负责内容管理工具条,包括相册的选择,管理相册按钮;

ContentListView负责贴图的主要页面部分,里面是一个个的ContentListItemView , ContentListView负责为每一个ContentListItemView的位置进行布局,每一个ContentListItemView只负责将本view的内容进行渲染;

结构如下:

-MyMainView

-TopView

-ContentView

-ContentTopView

-ContentListView

-ContentListItemView

-FooterView

为了简要说明, 以下没说明样式,请自行加入。

MyMainView.js:

 define(["backbone","TopView" ,"ContentView","FooterView] ,
function(Backbone , TopView , ContentView , FooterView){ var myMainView = Backbone.View.extend({
initialize :{
this.childrenView = [];
},
render:{
this.$el.html("<div id='topview'></div>");
this.$el.append("<div id='contentview'></div>");
this.$el.append("<div id='footerview'></div>"); var topView = new TopView({el:"#topview"});
this.childrenView.push(topview);
topview.render(); var contentView = new ContentView({el:"#contentview"});
this.childrenView.push(contentView);
contentView.render(); var footerView = new FooterView({el:"#footerview"});
this.childrenView.push(footerView);
footerView.render(); } , dispose : function(onlyDisposeChildren) {
//
if (!this.childrenViews
|| this.childrenViews.length == 0) {
if (!onlyDisposeChildren) {
this.remove();
}
return;
}
//
_.each(this.childrenViews, function(childView) {
if (childView.dispose) {
childView.dispose();
} else {
childView.remove();
}
});
//
this.childrenViews = [];
//
if (!onlyDisposeChildren) {
this.remove();
}
}
}); return myMainView;
});

MyMainView.js

利用Backbone划分View的好处就是,上层View只负责子层view的布局,而不需要关心子view的内容,具体的渲染工作交给子view去做,这样一个页面就可以划分为一个个的view,每一层view只关心本view的渲染和负责子view的布局。这样整个的页面开发更加有层次,并且打破常规的前端网页的开发模式,对于一个页面,可以多人进行开发,大大加快了效率。

定义好每一个View所需的参数

上面说到父view负责子view的布局,并且负责生成子view,所以子view需要的参数,也是由父view传给它;比如对于ContentListView:

 var contentListView = Backbone.View.extend({
initialize :function(data){
this.collection = data.collection;
this.COUNTPERROW = 5;
}, render :function(){ var self =this;
this.collection.each(function(aModel,index){ var row = null; // 每行设计5张图片
if (index % self.COUNTPERROW == 0) { row = $("<div class='row'></div>");
self .append(row);
} // 父view负责布局
var itemDiv= $("<div id='" + aModel.get("id)' + "></div>);
row.append(itemDiv); // 子view负责渲染
var itemView = new ContentListItemView({
el : itemDiv,
model :aModel
});
self.childrenView.push(itemView);
itemView.render(); }); },
});

contentListView

View之间独立开发

把整个页面的View划分好,并且将每一个的View的参数定义好后,就可以分配工作了,一个人负责几个View进行独立开发。

每一个View 要做的就三件事:

1、从上层取得渲染归属的dom节点 (this.$el) , 和所需参数;

2、本层负责在该dom节点中进行渲染;

3、为下层view布局,并传递数据

-前端开发注意事项

dom结构

网页是由一个个的Dom节点组成的,对于动态网页,需要动态对dom进行操作,在操作的过程尤其需要注意的是,在dom结构append到当前页面dom结构之前,该dom节点很有可能获取不到:

var div = $("<div id='test'></div>");
$("#test").html("ad"); this.$el.append(div);

在append到dom结构之前,就使用了id或class去查找dom接口,结果是没用的。
以上的方法可改为:

var div = $("<div id='test'></div>");
$(div).html("ad"); this.$el.append(div);

jquery提供给了很多的方法:

节点的操作

查找节点

var $var_1=$("htmltype");   //这句话就是获取所有htmltype节点

如:var ul1=ul1=(“ul”);

创建并追加节点

var $var_1=$("<htmltype>");//这句话是创建一个节点

$("htmltype2").append($var_1) ; //这句话是把节点插入所有htmltype2节点中

例子:

var $li_1=$("<li  title="title1">香蕉</li>");

     $("ul").append($li_1);

其中插入方法有以下几种:

append() 把B追加到A内部(所有的A元素,以下类似)
appendTo() 把A追加到B内部
prepend() 把B追加到A内部的内容前
prependTo() 把A追加到B的内容前
after() 在A后追加B
insertAfter() 在A前追加B
before() 在A前追加B
insertBefore()在A后追加B

例子:

$("ul").append("<li>你好</li>");//在ul内部追加li
$("<li>你好</li>").appendTo("ul");//在ul内部追加li

删除节点

remove() 删除该元素
empty() 清空节点,包括后代节点

例子:

$("ul  li:eq[1]").remove(); //获取ul中的第二个li并删除
$("ul li").remove(“li[title="菠萝"]”);//删除ul中li元素属性title="菠萝"的元素

复制节点

clone();//复制本节点 

例子:

$("ul  li:eq[1]").clone().appenTo("ul");//复制并追加到ul中,只复制是不会显示出来的

替换节点

replaceWith();//将B替换所有A
replaceAll();//将A替换所有B

包裹节点

warpAll();//用B包裹A
warpInner();//用B包裹A的内容

属性操作

获取和设置属性

var $var_1=$("p");//这句话是获取节点P
var $p_1=$var_1.attr("title");//获取节点P的title属性
var $p_2=$var_1.attr("title","你好");//设置节点P的title属性为"你好"

删除属性

$("p").removeAttr("title");//删除节点P的Title属性

样式操作

获取和设置样式

var $var_class=$("p").attr("class");//获取节点P的class属性
$("p").attr("class","class1");设置节点P的class属性为样式表类class1

追加样式

addClass() 添加样式到A 

例子:

$("p").addClass("another");添加样式表类another类到P

移除样式

removeClass() 移除类 

切换样式

toggleClass() 切换clss属性类为新的类 

判断某个样式是否存在

hasClass() 

内容的操作

html() 该方法获取html元素的内容,如:var var1=$("p").html();//获取P元素内的内容
text() 获取或设置某个html元素的内容
val() 获取元素的Value值
children() 获取html元素的所有子节点
next() 获取html元素后紧邻的同辈节点
prev() 获取html元素前紧邻的同辈节点
siblings() 获取html元素前后紧邻的同辈节点

CSS-DOM技术

css("属性","值") 设置元素css某个属性的值,如:$("p").css("color","red");//设置P的css属性{color:red;}

View手动销毁

由于Backbone 没有提供view的销毁机制, 所以在不使用的时候要手动将view清理掉,否则view始终存在于内存中,更糟糕的是这个view所有的绑定和监听事件都是有效的;如果没有手动清理view的习惯,那么一个请求很有可能就会被多次发送,而你却始终找不到问题的所在,这样不仅浪费网页内存,让你的网页由于存在大量view而奇卡无比 , 而且还会造成网络资源的浪费,服务器压力的倍增。
销毁函数可采用以下:

 dispose : function(onlyDisposeChildren) {
//
if (!this.childrenViews
|| this.childrenViews.length == 0) {
if (!onlyDisposeChildren) {
this.remove();
}
return;
}
//
_.each(this.childrenViews, function(childView) {
if (childView.dispose) {
childView.dispose();
} else {
childView.remove();
}
});
//
this.childrenViews = [];
//
if (!onlyDisposeChildren) {
this.remove();
}
}

View手动销毁

谨慎使用全局事件

在某些情况下,为了使得事件能够在全局范围内传播,可以将事件绑定在全局变量Backbone中。

this.listenTo(Backbone , "Event:Test" , this.HandleTest);

使用全局的确使得我们在事件触发和监听上获得了方便,但是需要特别谨慎的是,事件在view销毁之前会一直存在,如果该view没有调用remove方法,那么这个view和这个绑定事件就会一直存在的,由于是全局的事件,所以隐患很大。在切分View的时候,可能会分出几级的View视图出来,每一层View都可能会有事件监听,所以上一点说到的View销毁至关重要。另外在监听事件之前,最好先将当前事件进行解绑,让原有监听该事件的所有方法都失效,这样控制全局事件更加有效。

Backbone.off("Event:Test");

谨防js命名空间和css样式冲突

对于js命名空间冲突问题 , 可以使用requireJS来解决命名空间冲突问题,对于requireJs的使用可以参考文章:使用RequireJS实现异步加载脚本。

至于样式冲突问题,目前还没有很好地方式可以避免,我们在开发的过程中,每个人负责一部分模块,在开发的过程中,会共用到很多样式文件,尤其对于SIP开发,所以在样式问题上冲突时常发生,这个需要开发人员商定好统一的格式进行定义, 比如可以在模块的样式前加上模块名进行限定。比如对于bootstrap的 col-md-x样式 , 可能有些开发人员需要的栅栏布局的样式需要调整,就自己在css中添加了样式:

.col-md-12 {
margin : 0px 0px;
}

这样的整个系统中所有的col-md-12样式都会照着这个样式进行,而其他的需要的就是bootstrap 默然的样式,这样的错误非常容易出现,所在大家养成模块限定的好习惯:

#schedules .col-md-12 {
margin : 0px 0px;
}

以上的样式只覆盖了 schedules 下的所有col-md-12的样式,这样可以有效解决样式冲突问题,前提是需要每个开发人员进行有效预防。

Backbone前端开发流程及规范的更多相关文章

  1. 我在阿里这仨月 前端开发流程 前端进阶的思考 延伸学习的方式很简单:google 一个关键词你能看到十几篇优秀的博文,再这些博文中寻找新的关键字,直到整个大知识点得到突破

    我在阿里这仨月 Alibaba 试用期是三个月,转眼三个月过去了,也到了转正述职的时间.回想这三个月做过的事情,很多很杂,但还是有重点. 本文谈一谈工作中遇到的各种场景,需要用到的一些前端知识,以及我 ...

  2. 2022年Web前端开发流程和学习路线(详尽版)

    前言 前端侧重于人机交互和用户体验,后端侧重于业务逻辑和大规模数据处理.理论上,面向用户的产品里,所有问题(包括产品.设计.后端.甚至看不见的问题)的表现形式,都会暴露在前端,而只有部分问题(数据问题 ...

  3. web前端开发CSS命名规范参考

    做为一个web前端工程师,每天接触HTML.css就像吃饭一样,但是作为一名合作.优秀的web前端工程师,对DIV+CSS命名还是有一定的规范的,本文整理了一份web前端开发中DIV+CSS各种命名规 ...

  4. 实例讲解基于 React+Redux 的前端开发流程

    原文地址:https://segmentfault.com/a/1190000005356568 前言:在当下的前端界,react 和 redux 发展得如火如荼,react 在 github 的 s ...

  5. WEB前端开发流程总结

    作者声明:本博客中所写的文章,都是博主自学过程的笔记,参考了很多的学习资料,学习资料和笔记会注明出处,所有的内容都以交流学习为主.有不正确的地方,欢迎批评指正 WEB前端开发项目流程总结 1.新建项目 ...

  6. 前端开发流程之(线上)绝对地址(图片+css+js)

    重要提醒:前端写完-----发邮件通知项目组 1:写好的前段资源包上传到SVN上之后,相关的图片.CSS.js文件要换成线上地址给后台开发. 2:图片-----压缩(https://tinypng.c ...

  7. Web平台开发流程以及规范

    1.js和css的放的位置顺序与加载速度分析 为了让客户先看到效果,必须要先加CSS 如果在先head加载CSS,如果CSS大,会先下载CSS,再渲染HTML标签 如果CSS放在head中,当显示出H ...

  8. 前端开发 | 尝试用Markdown写一下近几个月的总结

    近期总结 回顾 半年前 半年前,接触了前端一年多(工作半年)的我了解的东西只有下面这些.因为在公司里的工作就是切静态页,捣鼓CMS. HTML (比较简洁的编写HTML) CSS/CSS3 (PC兼容 ...

  9. 淘宝前端工程师:国内WEB前端开发十日谈

    一直想写这篇"十日谈",聊聊我对Web前端开发的体会,顺便解答下周围不少人的困惑和迷惘.我不打算聊太多技术,我想,通过技术的历练,得到的反思应当更重要. 我一直认为自己是" ...

随机推荐

  1. C++ Style Languages: C++, Objective-C, Java, C#

    Hyperpolyglot.org From Hyperpolyglot.org C++ Style Languages: C++, Objective-C, Java, C# a side-by-s ...

  2. sprint2(第六天)

    昨天休息一天,今天继续做任务. 燃尽图:

  3. fullPage全屏高度自适应

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  4. mac下搭建MySql环境

    准备工作做完后,开始: 创建数据库 step1: 在mac中->系统偏好设置->最下边点MySQL 在弹出页面中 关闭mysql服务(点击stop mysql server) step2: ...

  5. C# 通过http post 请求上传图片和参数

    一.C# Winform或控制台 /// <summary> /// 通过http上传图片及传参数 /// </summary> /// <param name=&quo ...

  6. python基础(六)python操作excel

    一.python操作excel,python操作excel使用xlrd.xlwt和xlutils模块,xlrd模块是读取excel的,xlwt模块是写excel的,xlutils是用来修改excel的 ...

  7. Linux上两种网络连接方式

    模式一:NAT方式好处:路由器更换,或者交换机更换,网络仍然可以使用,所用使用最多 准备工作: 查看VMware服务器启动情况,五个全开模式 vmnet8开启模式 1 配置VMware交换机的ip地址 ...

  8. 10条SQL优化语句,让你的MySQL数据库跑得更快!

    慢SQL消耗了70%~90%的数据库CPU资源: SQL语句独立于程序设计逻辑,相对于对程序源代码的优化,对SQL语句的优化在时间成本和风险上的代价都很低: SQL语句可以有不同的写法: 1 不使用子 ...

  9. [转帖]MBR与UEFI

    从Intel 6系列主板之后,就开始提供UEFI BIOS支持,正式支持GPT硬盘分区表,一举取代了此前的MBR分区表格式,不过为了保持对老平台的兼容,微软即使最新的Windows 10系统也继续提供 ...

  10. vue 组件 子向父亲通信用自定义方法用事件监听

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>T ...