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 相关文章推荐
jsTree 基于JQuery的排序节点 Bug
Jul 26 Javascript
javascript自动给文本url地址增加链接的方法分享
Jan 20 Javascript
jQuery性能优化的38个建议
Mar 04 Javascript
jquery实现将获取的颜色值转换为十六进制形式的方法
Dec 20 Javascript
JavaScript驾驭网页-获取网页元素
Mar 24 Javascript
AngularJS ng-repeat指令中使用track by子语句解决重复数据遍历错误问题
Jan 21 Javascript
vue2.0中goods选购栏滚动算法的实现代码
May 17 Javascript
jQuery 添加样式属性的优先级别方法(推荐)
Jun 08 jQuery
js事件委托和事件代理案例分享
Jul 25 Javascript
[js高手之路]单例模式实现模态框的示例
Sep 01 Javascript
详解Webpack-dev-server的proxy用法
Sep 08 Javascript
jQuery 常用特效实例小结【显示与隐藏、淡入淡出、滑动、动画等】
May 19 jQuery
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
php中常用的预定义变量小结
2012/05/09 PHP
简单的php中文转拼音的实现代码
2014/02/11 PHP
几个实用的PHP内置函数使用指南
2014/11/27 PHP
php自定义函数转换html标签示例
2016/09/29 PHP
javascript 打印内容方法小结
2009/11/04 Javascript
js中关于new Object时传参的一些细节分析
2011/03/13 Javascript
Javascript中正则表达式的全局匹配模式分析
2011/04/26 Javascript
js中opener与parent的区别详细解析
2014/01/14 Javascript
jQuery zTree加载树形菜单功能
2016/02/25 Javascript
超漂亮的Bootstrap 富文本编辑器summernote
2016/04/05 Javascript
浅谈JavaScript前端开发的MVC结构与MVVM结构
2016/06/03 Javascript
jquery延迟对象解析
2016/10/26 Javascript
BootStrap modal模态弹窗使用小结
2016/10/26 Javascript
React简单介绍
2017/05/24 Javascript
全面介绍vue 全家桶和项目实例
2017/12/27 Javascript
Vue组件通信之Bus的具体使用
2017/12/28 Javascript
微信小程序如何修改radio和checkbox的默认样式和图标
2019/07/24 Javascript
layui插件表单验证提交触发提交的例子
2019/09/09 Javascript
微信小程序实现滑动操作代码
2020/04/23 Javascript
Python快速转换numpy数组中Nan和Inf的方法实例说明
2019/02/21 Python
Python面向对象编程基础实例分析
2020/01/17 Python
python except异常处理之后不退出,解决异常继续执行的实现
2020/04/25 Python
Django中文件上传和文件访问微项目的方法
2020/04/27 Python
关于tf.matmul() 和tf.multiply() 的区别说明
2020/06/18 Python
Python爬虫实现HTTP网络请求多种实现方式
2020/06/19 Python
解决TensorFlow训练模型及保存数量限制的问题
2021/03/03 Python
XD健身器材:Kevlar球、Crossfit健身球
2019/03/26 全球购物
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
大学生毕业的自我鉴定
2013/11/13 职场文书
工程资料员岗位职责
2014/03/10 职场文书
基督教婚礼主持词
2014/03/14 职场文书
小学生常见病防治方案
2014/06/06 职场文书
单位接收函格式
2015/01/30 职场文书
挂职锻炼工作总结2015
2015/05/28 职场文书
学生安全责任协议书
2016/03/22 职场文书
Vue提供的三种调试方式你知道吗
2022/01/18 Vue.js