AngularJS入门知识之MVW类框架的编程思想探讨


Posted in Javascript onDecember 08, 2014

本文通过实现两个简单的业务需求,探讨AngularJS和传统的JavaScript控制DOM实现方式的差别,并尝试理解MVW此类框架在流行的Web前端开发中的编程思想。

这个需求很常见,比如,一个两级菜单,在第一级别菜单项点击时候,对应的子菜单项目应该显示或隐藏。

jQuery的实现:

<!-- html -->

<ul class="parent">

    <li class="parent_item">

        Item 1

        <ul class="child">

            <li class="child_item">Item child 1</li>

        </ul>

    </li>

</ul>
// javascript

$('li.parent_item').click(function(){

    $(this).children('ul.child').toggle();

})

AngularJS的实现:

<!-- html -->

<ul>

    <li ng-click="hide_child = !hide_child">

        Item 1

        <ul ng-hide="hide_child">

            <li>Item child 1</li>

        </ul>

    </li>

</ul>

传统操作DOM的方式,不再赘述。AngularJS的实现,相对代码要精炼很多,只有HTML的版本即可。以上代码,用到了AngularJS这些知识点:

1.Directives 

2.Expressions

ng-click和ng-hide都是框架自带的Directives(指令),前者相当于给li标签提供了一个Event Handler,在该HTML元素(li)被点击的时候,会执行hide_child = !hide_child这个Expression(表达式)。我们先看一下ng-hide这个指令,它会根据赋值的表达式结果(布尔值)来控制该HTML元素是否要显示(通过CSS实现)。也就是说,如果hide_child这个变量如果是true,那么ul就会被隐藏,否则结果相反。  

这里hide_child其实是$scope上的一个变量,对它的值的变更,也可以用controller控制器包装一个方法来实现,只不过现在的语句比较简单,直接写在了指令的赋值里面。

通过以上简单的代码分析,我们可以看到AngularJS两个比较明显的特点:

1.通过指令和表达式对DOM的操作进行了封转,只需简单的代码便可省去额外的JavaScript代码
2.指令和表达式的应用,只直接嵌套在HTML中的,这和jQuery推从的Unobtrusive JavaScript的代码风格有些背道而驰

我们先看另外一个需求,再详细解释上面的结论。

需求2:通过点击div,触发选择form中的一个radio button
传统的HTML Form元素,在如今的移动设备上,操作起来并不是十分友好。比如,Radio button单选框,在触摸屏上,需要精确的位置定位,才能控制好这个组件,但是手指定位又很粗糙。常见的做法,是添加一个对应的Label控件,但是文字本身占屏比例也并不理想,而且也不具备明确的信息传达效果。所以,通常会间接操作一个区域比较大的div或者li标签。

jQuery的实现:

<!-- html -->

<ul>

    <li class="selection">

        <input type="radio"

            id="option1" />

        <label for="option1">option 1</label>

    </li>

</ul>
// javascript

$('li.selection').click(function(){

    $(this).children('input[type="radio"]').click();

})

AngularJS的实现:

<!-- html -->

<ul>

    <li ng-repeat="option in options"

        ng-click="model.option = option.value"

        ng-class="{active: model.option == option.value}" >

        <input type="radio"

            ng-model="model.option"

            value="{{option.value}}"

            id="option1" />

        <label for="option1">option 1</label>

    </li>

</ul>

在这个解决方案中,我们同样没有涉及到额外的JavaScript代码,并且多用了几个指令。为了对比参照,我们只关心ng-click和ng-model这两个指令的表达式。

我们先看一下input这个元素的ng-model指令,这里赋值的意思是,我们把模板上的input和$scope.model对象的option属性进行了关联,深入了解数据绑定可以参考Data Binding。这种指定关联,使得模板控件直接和数据Model进行了绑定,并且这种绑定是双向的。意味着,一旦用户修改控件中的值(勾选radio input),对应的Model对象就会重新赋值(model.option);同时,如果Model对象的值发生了变化,模板中的input控件也会对应反映变化。而这点,在上述jQuery的实现中,其实是没有做到的。

所以,这里通过AngularJS的数据绑定,点击li元素间接完成触发input的流程是这样子的:

1.点击li标签,给model.option赋值;
2.修改了Model对象,定位到对应input控件(value的值为model.option那个);
3.激活input控件的checked属性

通过以上两个案例,我们对Web前端的操作有了新的认识。

首先,技术实现上,通过引入新的指令,表达式,数据绑定等概念,我们可以完全新的方式去操作DOM,而不仅仅局限在用户和HTML组件交互操作上的JavaScript代码的实现。这种思想的变化是巨大的。

从本世纪初,动态Web编程的兴起开始,服务器端的编程技术一直在改进。从一开始的CGI/PHP/ASP,由语言和平台产生了.NET vs. Java,开发效率和软件过程促进了MVC框架/ORM/AOP等,性能和大数据带来了NodeJS/NoSQL/Hadoop等,而浏览器前端的技术需求似乎没有那么激进过。一方面,通过服务器端和数据库,大部分B/S模型的业务需求都能满足;再者,浏览器本身存在不同平台的差异性,对脚本语言和渲染技术的标准不兼容,以及运算能力的欠缺和安全性的考虑。

在这种情况下,浏览器端的需求,大部分时候只需要考虑渲染页面和简单的用户交互。HTML/DOM加上JavaSript/CSS就这样成就了前端的主要工作。所以,以前是没有前端工作师,只需要Web设计师的。慢慢对前端的要求多起来,jQuery成为使用程度最高的一个JavaScript操作DOM的封装库。而在这个阶段,jQuery/JavaScript的主要任务,仍然只是作为面向用户浏览器终端呈现和交互的工具。

理解了jQuery的起源,我们不难发现,以前追求的一些规则,譬如Unobtrusive JavaScript,当时局限于实现的手段和方式,为了分离DOM和JavaScript代码逻辑,我们优先选择了维护性更高的方式。前端对JavaScript的需求加大之后,出现了很多MVC/MVP的前端框架,以及AngularJS所谓的MVW(Model-View-Whatever),JavaScript和DOM一刀切的方式发生了变化。原先我们考虑界面显示和用户交互的直接操作,现在我们有了客户端的数据绑定,丰富的指令,依赖注入,等待我们的将是全新的编程模型和思维方式。 

Javascript 相关文章推荐
用 javascript 实现的点击复制代码
Mar 24 Javascript
JavaScript DOM 学习第三章 内容表格
Feb 19 Javascript
轻轻松松学JS调试(不下载任何工具)
Apr 14 Javascript
javascript 树形导航菜单实例代码
Aug 13 Javascript
DOM 高级编程
May 06 Javascript
详解JS-- 浮点数运算处理
Nov 28 Javascript
Angular2中select用法之设置默认值与事件详解
May 07 Javascript
浅谈node中的exports与module.exports的关系
Aug 01 Javascript
基于node.js实现微信支付退款功能
Dec 19 Javascript
Vue瀑布流插件的使用示例
Sep 19 Javascript
微信小程序实现简单评论功能
Nov 28 Javascript
VUEX-action可以修改state吗
Nov 19 Javascript
Js中使用hasOwnProperty方法检索ajax响应对象的例子
Dec 08 #Javascript
ECMAScript5中的对象存取器属性:getter和setter介绍
Dec 08 #Javascript
JavaScript对象之深度克隆介绍
Dec 08 #Javascript
SeaJS 与 RequireJS 的差异对比
Dec 08 #Javascript
JavaScript中的ArrayBuffer详细介绍
Dec 08 #Javascript
JS实现仿京东淘宝竖排二级导航
Dec 08 #Javascript
js继承call()和apply()方法总结
Dec 08 #Javascript
You might like
GD输出汉字的函数的分析
2006/10/09 PHP
解析将多维数组转换为支持curl提交的一维数组格式
2013/07/08 PHP
Session的工作机制详解和安全性问题(PHP实例讲解)
2014/04/10 PHP
PHP获取MySql新增记录ID值的3种方法
2014/06/24 PHP
PHP实现的数独求解问题示例
2017/04/18 PHP
PHP绕过open_basedir限制操作文件的方法
2018/06/10 PHP
使用SMB共享来绕过php远程文件包含的限制执行RFI的利用
2019/05/31 PHP
PHP实现爬虫爬取图片代码实例
2021/03/03 PHP
js的event详解。
2006/09/06 Javascript
javascript 处理HTML元素必须避免使用的一种方法
2009/07/30 Javascript
JavaScript 存在陷阱 删除某一区域所有节点
2010/05/10 Javascript
jquery 圆形旋转图片滚动切换效果
2011/01/19 Javascript
基于jQuery捕获超链接事件进行局部刷新代码
2012/05/10 Javascript
解析JavaScript中的不可见数据类型
2013/12/02 Javascript
JavaScript中的object转换函数toString()与valueOf()介绍
2014/12/31 Javascript
Javascript实现颜色rgb与16进制转换的方法
2015/04/18 Javascript
JS实现的自定义水平滚动字体插件完整实例
2016/06/17 Javascript
jQuery Ajax 加载数据时异步显示加载动画
2016/08/01 Javascript
Google Maps基础及实例解析
2016/08/06 Javascript
详解react如何在组件中获取路由参数
2017/06/15 Javascript
微信小程序“摇一摇”的实例代码
2017/07/20 Javascript
NodeJS实现视频转码的示例代码
2017/11/18 NodeJs
vue实现两个组件之间数据共享和修改操作
2020/11/12 Javascript
浅析python递归函数和河内塔问题
2017/04/18 Python
python 3.7.0 安装配置方法图文教程
2018/08/27 Python
Python+OpenCV采集本地摄像头的视频
2019/04/25 Python
Django Sitemap 站点地图的实现方法
2019/04/29 Python
详解h5页面在不同ios设备上的问题总结
2019/03/01 HTML / CSS
厨房工作人员岗位职责
2013/11/15 职场文书
经理秘书找工作求职信
2013/12/19 职场文书
工作的心得体会
2013/12/31 职场文书
士力架广告词
2014/03/20 职场文书
在职人员跳槽求职信
2015/03/20 职场文书
2019学校请假条格式及范文
2019/06/25 职场文书
js Proxy的原理详解
2021/05/25 Javascript
SQL SERVER中的流程控制语句
2022/05/25 SQL Server