【大前端之前后分离02】前端模板嵌套问题

回顾

接上文:【大前端之前后分离01】JS前端渲染VS服务器端渲染,我们探讨了为什么要做前后分离,以及前端渲染需要解决的问题,最后提出了自己的解决方案:

前端代码编译形成两套代码:①前端发布版本 + ②服务器端脚本

这个想法借鉴了fis plus的smarty模块化思维,以及reactJS编译运行的概念,上次初步论证了其可行性,也遗留了一些问题,其中比较关键的问题是:

前端模块嵌套问题

我们在一个模板中又有一个widget,在子模板中又有一个widget,父模块与子模块中有数据依赖,或者子模块为一个循环,循环却依赖父模块某个值,这个便很麻烦。

举个例子来说,我们首页引入了一个商品模块,商品类型模块为一循环模块,里面又有子模块:

index首页模块:

1 <div id="type_widget_wrapper">
2   <script type="text/javascript">
3     render(‘text!./template/type.html‘, ‘./model/type‘, ‘./controller/type‘, ‘type_widget_wrapper‘);
4   </script>
5 </div>

type模块:

 1 <ul id="type_id">
 2     <% for (var i = 0, len = data.length; i < len; i++) { %>
 3     <li class="type js_type">
 4         <h2><%=data[i].name%></h2>
 5         <ul class="product_list">
 6             <% for (var j = 0, len1 = data[i].product.length; j < len1; j++) { %>
 7                 <li class="product">
 8                     <%=data[i].product[j].name%>
 9                 </li>
10             <% } %>
11         </ul>
12     </li>
13     <% } %>
14 </ul>

可以看到,其中有第二次循环迭代的将该类型的商品信息读出,如果我们想将商品信息模块化的,这里便出现了模块嵌套情况:

 1 <ul id="type_id">
 2     <% for (var i = 0, len = data.length; i < len; i++) { %>
 3     <li class="type js_type">
 4         <h2><%=data[i].name%></h2>
 5         <ul class="product_list">
 6         <div id="product_list_widget_wrapper">
 7           <script type="text/javascript">
 8             render(‘text!./template/product_list.html‘, ‘./model/product_list‘, ‘./controller/product_list‘, ‘product_list_widget_wrapper‘);
 9           </script>
10         </div>
11         </ul>
12     </li>
13     <% } %>
14 </ul>

这里暂时不考虑子模块中还有异步数据请求问题,我们将列表对应的模板放到了单个文件中:

1 <% for (var j = 0, len1 = data[i].product.length; j < len1; j++) { %>
2     <li class="product">
3         <%=data[i].product[j].name%>
4     </li>
5 <% } %>

这里的循环解析便是我们今天研究的重点,因为前端模块至少需要两个条件:

① 唯一的dom容器

② 能获取父级模块的相关数据

为了解决这个问题,我这里提出了迭代模块的概念。

迭代模块

所谓迭代模块,便是用于数据内嵌形式,并且处于循环中的模块,比如上述例子,我整个type模板就变成了这样(这里为最简形式):

 1 <ul id="type_id">
 2   <% for (var i = 0, len = data.length; i < len; i++) { %>
 3   <li class="type js_type">
 4     <h2>
 5       <%=data[i].name%></h2>
 6     <ul class="product_list">
 7
 8       <div id="data_inner_widget_wrapper_<%=i %>">
 9         <script type="text/javascript">
10           iteratorRender({
11             index: typeof <%=i%> == ‘string‘ ? ‘<%=i%>‘ : <%=i%>,
12             value: <%=JSON.stringify(data[i])%>,
13             name: ‘data_inner‘
14           });
15         </script>
16       </div>
17
18     </ul>
19   </li>
20   <% } %>
21 </ul>

这个是编译过后形成的前端代码,最初是这样的:

 1 <ul id="type_id">
 2   <% for (var i = 0, len = data.length; i < len; i++) { %>
 3   <li class="type js_type">
 4     <h2>
 5       <%=data[i].name%></h2>
 6     <ul class="product_list">
 7         <%iteratorWidget({
 8           index: <%=i%>,
 9           value: <%=JSON.stringify(data[i])%>,
10           name: ‘data_inner‘,
11         }); %>
12     </ul>
13   </li>
14   <% } %>
15 </ul>
1 <%iteratorWidget({
2   index: <%=i%>, //索引,整数或者字符串
3   value: <%=JSON.stringify(data[i])%>, //对应数据对象,字符串或者json对象
4   name: ‘data_inner‘,
5 }); %>

这个时候前端需要实现iteratorRender方法,首先前端模板将上述代码解析结束后是这个样子的:

 1 "<ul id="type_id">
 2
 3   <li class="type js_type">
 4     <h2>
 5       电脑</h2>
 6     <ul class="product_list">
 7
 8       <div id="data_inner_widget_wrapper_0">
 9         <script type="text/javascript">
10           iteratorRender({
11             index: typeof 0 == ‘string‘ ? ‘0‘ : 0,
12             value: {"id":1,"name":"电脑","product":[{"name":"戴尔"},{"name":"苹果"},{"name":"联想"},{"name":"华硕"}]},
13             name: ‘data_inner‘
14           });
15         </script>
16       </div>
17
18     </ul>
19   </li>
20
21   <li class="type js_type">
22     <h2>
23       书籍</h2>
24     <ul class="product_list">
25
26       <div id="data_inner_widget_wrapper_1">
27         <script type="text/javascript">
28           iteratorRender({
29             index: typeof 1 == ‘string‘ ? ‘1‘ : 1,
30             value: {"id":2,"name":"书籍","product":[{"name":"三国演义"},{"name":"西游记"},{"name":"红楼梦"},{"name":"水浒传"}]},
31             name: ‘data_inner‘
32           });
33         </script>
34       </div>
35
36     </ul>
37   </li>
38
39   <li class="type js_type">
40     <h2>
41       游戏</h2>
42     <ul class="product_list">
43
44       <div id="data_inner_widget_wrapper_2">
45         <script type="text/javascript">
46           iteratorRender({
47             index: typeof 2 == ‘string‘ ? ‘2‘ : 2,
48             value: {"id":3,"name":"游戏","product":[{"name":"仙剑1"},{"name":"仙剑2"},{"name":"仙剑3"},{"name":"仙剑4"}]},
49             name: ‘data_inner‘
50           });
51         </script>
52       </div>
53
54     </ul>
55   </li>
56
57 </ul>

 1 <li class="type js_type">
 2   <h2>
 3     电脑</h2>
 4   <ul class="product_list">
 5
 6     <div id="data_inner_widget_wrapper_0">
 7       <script type="text/javascript">
 8         iteratorRender({
 9           index: typeof 0 == ‘string‘ ? ‘0‘ : 0,
10           value: { "id": 1, "name": "电脑", "product": [{ "name": "戴尔" }, { "name": "苹果" }, { "name": "联想" }, { "name": "华硕"}] },
11           name: ‘data_inner‘
12         });
13       </script>
14     </div>
15
16   </ul>
17 </li>

然后前端方法的实现为:

 1 //最简单实现,仅考虑渲染,不严谨
 2 var iteratorRender = function (opts) {
 3   var name = opts.name;
 4   var index = opts.index;
 5   var data = typeof opts.value == ‘string‘ ? JSON.parse(opts.value) : opts.value;
 6   var wrapperId = name + ‘_widget_wrapper_‘ + index;
 7   var template = ‘text!./template/‘ + name + ‘.html‘;
 8   var controller = ‘./controller/‘ + name;
 9
10   require([template, controller], function (tpl, view) {
11     var html = $(_.template(tpl)(data));
12     var wrapper = $(‘#‘ + wrapperId);
13     html.insertBefore(wrapper);
14     wrapper.remove();
15     //执行控制器
16     view.init();
17   });
18 }

然后代码运行,逻辑跑通了:

结语

由于最近工作强度上来了,解决了前端渲染时候的模板嵌套问题,一直拖到了今天,服务器端的模板嵌套更好处理,该方案后续会继续细化

时间: 2024-11-06 09:47:47

【大前端之前后分离02】前端模板嵌套问题的相关文章

【大前端之前后分离】JS前端渲染VS服务器端渲染

前言 之前看了一篇文章:@Charlie.Zheng Web系统开发构架再思考-前后端的完全分离,文中论述了为何要前后分离,站在前端的角度来看,是很有必要的:但是如何说服团队使用前端渲染方案却是一个现实问题,因为如果我是一个服务器端,我便会觉得不是很有必要,为什么要前后分离,前后分离后遗留了什么问题,如何解决,都得说清楚,这样才能说服团队使用前端渲染的方案,而最近我刚好遇到了框架选型的抉择. 来到新公司开始新项目了,需要做前端框架选型,因为之前内部同事采用的fis框架,而这边又是使用的php,这

大前端 前后端分离带来的好处

大前端 前后端分离带来的好处:1. 前后端分离开发,相互之间的影响很小2. 使用 webpack,模块化打包前端代码3. 在开发时,可以做到代码热替换,可以使用 babel,可以使用 css 预处理器等等4. 打包时,打包代码的同时还可以做到按需加载代码,静态文件地址自动写入 html 标签,压缩 css.js 代码.压缩图片5. NPM 管理依赖 除了享受不到前后端分离的优点外,还会1. 放弃 ES6,只能写 ES5 以下版本的代码,且要自己处理一些兼容问题2. 不能够使用 A.R.V 三大框

localStorage + 配置url 前后端分离之前端先行

关于localStorage和sessionStorage的基础说明说明网上一大堆,这里说下自己的一个亲身应用. 使用localStorage配置url,使前端代码更方便适配测试和真实环境: 大家都知道如果前后端分离的话,往往很多时候可以前端先行,不依赖于后台(接口得提前定义好). 但是存在两个问题: 1.前后端分离后前端虽然不依赖于后台,但是依赖ajax返回的结果 2.往往自己造的mock地址跟真是环境的url地址不一致,如果写死了,则需要改动很大一片 先说第二个问题,之前在一个项目上看到的时

前后端分离, 前端如何防止直接输入URL进入页面?

转自:https://blog.csdn.net/weixin_41829196/article/details/80444870 前后端分离,如何防止用户直接在地址栏输入url进入页面,也就是判断用户是否登录,没有,则直接跳转到登录页,后台可以用session记录用户登陆的状态,疑问的是前端每次ajax请求,都要做状态判断么,没登录就location.href="login.html",还是有什么别的写法?请教大神,重点想知道前端是如何写的,求demo, 另外就是单页面应用上,前端又

大公司和小公司的web前端岗位,工作内容有哪些不同?

web前端岗位可以做哪些工作? 泛泛来说,会有这么些岗位: 网页制作.网页制作工程师.前端制作工程师.网站重构工程师.前端开发工程师.资深前端开发工程师.前端架构师. 当然,对于不同规模的公司,web前端岗位的设定也是有区别的,下面就来给大家介绍一下,企业是如何根据规模大小设定web前端的岗位的. ▼ 1. 企业规模:10人以下 我们先从几个人的小作坊说起,这种小作坊里面,基本上有一个人负责页面的设计,然后把页面"切"出来,然后有一个专门的人负责套程序.在这样的公司里面,Web前端其实

7个Web前端极其精美的动画效果模板(附源码)

1.  jQuery动态随机背景滚动 源码下载  /  在线演示 2.  jquery animate分页按钮 源码下载 /  在线演示 3. html5+css3日食场景特效 源码下载/   在线演示 4. HTML5小球碰撞叠加 鼠标点击拨弄,能在支持 FireFox.Chrome.Safari.傲游.搜狗.360浏览器. 源码下载/   在线演示 5.  css3实现天气图标 源码下载/  在线演示 6.  css3图片变形特效   源码下载/  在线演示 7. jquery心电图跳动 源

Web前端,HTML5开发,前端资源,前端网址,前端博客,前端框架整理 - 转

Web前端/H5开发,前端资源,前端网址,前端博客,前端框架整理 - 转 综合类 前端知识体系 前端知识结构 Web前端开发大系概览 Web前端开发大系概览-中文版 Web Front-end Stack v2.2 免费的编程中文书籍索引 前端书籍 前端免费书籍大全 前端知识体系 免费的编程中文书籍索引 智能社 - 精通JavaScript开发 重新介绍 JavaScript(JS 教程) 麻省理工学院公开课:计算机科学及编程导论 JavaScript中的this陷阱的最全收集--没有之一 JS

WEB前端开发电商网站前端架构

课程介绍通过一个垂直电子商务网站,介绍前端架构搭建和实现的步骤和方法,以及在这个过程中我们需要做什么才能帮助项目最终从设计走向实现.课程提纲第1章 前端架构知识准备认识前端架构,了解前端架构技术.产品设计和发布.数据分析和优化的基础第2章 前端架构设计了解前端架构的组织方式.页面层次的架构组织.架构设计和组件化方案等.第3章 前端架构实施了解架构的实施.优化思路,如何实施自动化.通过蛋糕电商网站讲解,分析案例.如何图解设计和交互图.如何从目录入手搭建基本架构.如何从页面层次进行架构搭建和最后项目

搭建前端的开发环境和前端开发流程总结

一.搭建前端的开发环境 1.代码编辑工具:sublime/WebStorm/HBuilder. 2.断点调试工具:Firebug. 3.版本管理工具:Git(本人建议使用git,至于原因大家可以看看相关blog),安装完成后我们就可以从github上clone一些项目. 4.代码合并和混淆工具:webpack (Webpack具有Grunt.Gulp对于静态资源自动化构建的能力,同时兼容AMD与CMD的模块加载规范). 4.开发调试工具:NodeJs.很多非常有用的工具都是基于NodeJs的,我