angularjs + seajs构建Web Form前端(三) -- 兼容easyui
回顾
在上一章中使用了angular实现了ajax form和树形结构,经过以上两章对于angular的大致使用,对于angular也有了初步的认识,接下来的内容只会对angular的一些用法做简单的说明,如果有不清楚的可以自己查看angular API或者留言给我。
刚开始接触angular的时候,我以为会抛弃诸如jQueryUI、easyui这样的ui组件,但是随着我学习后才发现,其实是我被自己的想法给误导、局限了。mvvm通过数据与ui的绑定,实现双向的同步,使用其他ui的组件我们一样可以通过数据的变化来实现ui组件的状态变化,通过ui组件的一些变化来变更绑定的数据也是行的通的。
问题
1、input类型控件
2、列表类型控件
3、C#扩展
input类型控件
由于easyui大部分的控件都可以基于input,如validatebox、datebox、numberbox等,试着使用ngModel直接在这些控件上进行绑定,代码如下:
- //html
- <div id="main" ng-controller="MainController">
- 名字:<input type="text" ng-model="editData.name" />
- <br />
- 年龄:<input name="age" class="easyui-numberbox" ng-model="editData.age" />
- <br />
- <a href="#" class="easyui-linkbutton" ng-click="save()">保存</a>
- </div>
- //js
- angular.module('test', []).controller('MainController', function ($scope) {
- var age = $('[numberboxname=age]');
- $scope.editData = {};
- $scope.save = function () {
- console.log($scope.editData);
- $scope.editData = {};
- };
- });
当点击保存的时候,发现代码是运行正常的,可以在控制台内看到名字和年龄的值,但是这里有一个BUG,那就是当保存数据以后,要再次输入年龄的时候,年龄还是显示上次输入的值,因此需要在重置editData的时候将numberbox的值设置为默认值,代码就不写了。
列表类型控件
像numberbox、validatebox、datebox等input类型控件,都可以通过ngModel加上一些代码来实现数据的双向绑定,相对来说还是很简单的,但是像combo、combobox、combotree等就没办法直接使用ngModel进行绑定了,因为这些控件会生成额外的html代码,这是NG无法控制到的,因为这些控件的一些自身的事件机制并不能在ng内发挥作用,相反还会影响ng的正常运行,因此只能根据自身的业务来对它们进行一些扩展,这里以combobox为例子,实现思路大致如下:
1、自定义指令生成下拉单html
2、手动初始化combobox并将绑定字段的值设置到combobox上
3、当combobox选择值的时候将值更新到绑定的字段上
根据以上思路,实现代码如下:
- //其他的省略
- .directive('esCombobox', function () {
- return {
- replace: true,
- restrict: 'E',
- template: '<select></select>',
- scope: {
- data: '=',
- value: '@'
- },
- link: function (scope, element, attrs) {
- var props = scope.value.split('.');
- var current = getBinder();
- element.combobox({
- data: scope.data,
- onSelect: function (r) {
- var binder = getBinder();
- binder.obj[binder.field] = r.value;
- }
- }).combobox('setValue', current.obj[current.field]);
- function getBinder() {
- return props.length == 1 ? {
- obj: scope.$parent,
- field: props[0]
- } : {
- obj: scope.$parent[props[0]],
- field: props[1]
- };
- };
- }
- };
- });
以上方法之所以要将getBinder独立出来,是因为每次操作的绑定对象都是不同的(editData在保存之后会被重新赋值,引用的对象不同了)。
C#扩展
有时候当我们使用服务端脚本来生成html的时候,我们可能会使用如下代码来进行绑定:
- <input type="text" ng-model="editData.name" ng-init="editData.name='<%=Model.Name %>'"/>
以上html代码可以发现,editData.name是绑定的字段,而ngInit内初始化赋值可以直接从Model中获取,我们可以创建一个NgModelAttribute的特性,然后该特性内提供一个属性用来存储绑定的字段,大致代码如下:
- [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
- public class NgModelAttribute : Attribute, ITagBuilderWrapper
- {
- private string m_BindName;
- public string BindName { get { return m_BindName; } }
- public NgModelAttribute(string bindName)
- {
- m_BindName = bindName;
- }
- }
然后使用服务端脚本生成Html的时候,获取表达式指定的属性包含的NgModelAttribute特性以及Model的值来生成以上的html,大致代码如下:
- public static string Control(string tag, Expression<Func<TModel, object>> exp, TModel model)
- {
- var builder = new TagBuilder(tag);
- string propertyName = PropertyHelper.ResolveName(exp);
- var property = model.GetType().GetProperty(propertyName);
- var attrs = property.GetCustomAttributes(typeof(NgModelAttribute), false);
- if (attrs.Length > 0)
- {
- var ngModel = attrs[0] as NgModelAttribute;
- builder.AddAttribute("ng-model", ngModel.BindName);
- if (model != null)
- {
- var propertyValue = property.GetValue(model, null);
- string initValue;
- if (property.PropertyType == typeof(string) || property.PropertyType == typeof(Guid))
- {
- initValue = string.Format("'{0}'", propertyValue.ToString());
- }
- else if (property.PropertyType == typeof(DateTime))
- {
- try
- {
- var date = Convert.ToDateTime(propertyValue);
- initValue = string.Format(
- "new Date(1970, 0, 1, 0, 0, {0})",
- Convert.ToInt32((date - new DateTime(1970, 1, 1)).TotalSeconds));
- }
- catch
- {
- initValue = "new Date()";
- }
- }
- else
- {
- initValue = propertyValue.ToString();
- }
- builder.AddAttribute("ng-init", string.Format("{0}={1}", ngModel.BindName, initValue));
- }
- }
- return builder.ToString();
- }
以上代码仅作为参考,其中大部分的代码主要是用于判断绑定ngInit的值,因为不同值绑定的方式不同。那么接下来只要将最初的代码改为如下:
- //html
- <%=HtmlHelper.Control<Person>("input", p => p.Name, Person)
- //ViewModel
- public class Person
- {
- [NgModel("editData.name")]
- public string Name { get; set; }
- }
生成的结果跟原来的是一样的,这样就完成了对NG的扩展了。
结尾
由于此次是在学习angular的过程当中,遇到了控件组的问题,由于本人对于css实在是很烂,无法实现漂亮的组件于是我就放弃了,便有了想要继续使用easyui的念头,但是引入easyui后发现它与bootstrap存在着样式兼容性问题,因此移除了bootstrap,但是编码当中发现了2个库之间的各种原理上的冲突,经过几次失败之后,终于找到了可以将2者结合在一起的方法,因此就有了此篇文章,希望此次分享能给其他人带来帮助,如果存在问题或者错误的话,请告诉我,谢谢。
angularjs + seajs构建Web Form前端(三) -- 兼容easyui的更多相关文章
- bootstrap + angularjs + seajs构建Web Form前端2
bootstrap + angularjs + seajs构建Web Form前端(二) 回顾 上一篇讲解了引入bootstrap构建一个简单的登录页面,如何让angularjs自动启动并绑定视图,操 ...
- bootstrap + angularjs + seajs构建Web Form前端(1)
bootstrap + angularjs + seajs构建Web Form前端(一) 简介 Bootstrap是Twitter推出的一个用于前端开发的开源工具包,它由Twitter的设计师Mark ...
- angularjs + seajs构建Web Form前端(一)
简介 Bootstrap是Twitter推出的一个用于前端开发的开源工具包,它由Twitter的设计师Mark Otto和Jacob Thornton合作开,是一个CSS/HTML框架. Angula ...
- angularjs + seajs构建Web Form前端(二)
回顾 上一篇讲解了引入bootstrap构建一个简单的登录页面,如何让angularjs自动启动并绑定视图,操作过程当中如何使用ui-bootstrap,继而完成简单功能后如何引入seajs后如何使n ...
- angularjs + seajs构建Web Form3
angularjs + seajs构建Web Form前端(三) -- 兼容easyui 回顾 在上一章中使用了angular实现了ajax form和树形结构,经过以上两章对于angular的大致使 ...
- 利用Eclipse中的Maven构建Web项目(三)
利用Eclipse中的Maven构建Web项目 1.将Maven Project转换成动态Web项目,鼠标右键项目,输入"Project Facets" 2.依据Dynamic W ...
- seajs构建web申请书
随着开发项目的不断扩大,查找代码依赖关系复杂化,维护比较沉闷.记seajs有这种效果方面.果断尝鲜.解决两个问题:1)命名冲突 2)文件相关性 因为所在BG使用TAF服务,基于C++开发一套WSP w ...
- IDEA+Maven+Tomcat构建Web项目的三种方法
[本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究.若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!] 本文将介绍三种方 ...
- 构建高性能WEB站点笔记三
构建高性能WEB站点笔记三 第10章 分布式缓存 10.1数据库的前端缓存区 文件系统内核缓冲区,位于物理内存的内核地址空间,除了使用O_DIRECT标记打开的文件以外,所有对磁盘文件的读写操作都要经 ...
随机推荐
- Linux安装snmp
1.yum安装 yum -y install net-snmp* 2.修改配置文件/etc/snmp/snmpd.conf com2sec notConfigUser default public 默 ...
- Yii2中系统定义的常用路径别名,如果获取web的url
下面这些别名都是在Yii2里面系统定义的,可以直接拿来就用 '@yii' => '@yii/swiftmailer' => string 'C:\wamp\www\advanced\ven ...
- iOS开发-【C语言】三目运算符
1.N目运算符 像逻辑非(!).负号(-)这种只连接一个数据的符号,称为“单目运算符”,比如!5.-5.像算术运算符.关系运算符.逻辑运算符这种连接二个数据的负号,称为“双目运算符”,比如6+7.8* ...
- IT 需要知道的一些专业名词和解释 (长期更新)
c2c: 就是我卖东西你来买 (comsumer to comsumer个人对个人) b2c: 就是我开公司卖东西你来买 (business to comsumer 公司对个人) o2o: 就是我开 ...
- 使用Maven编译项目遇到——“maven编码gbk的不可映射字符”解决办法 ——转载
一.问题描述 今天在MyEclipse中使用Maven编译项目源代码时,结果如下了如下的错误
- 学javascript必须要知道的事
第一:变量声明 在使用javascript时使用变量时首先做的是声明变量,变量声明的关键字是var. 例子: var i; var sum; 也可以多个变量声明: var i,sum; 还可以在声明时 ...
- 关于多线程与CRITICAL_SECTION的使用
CRITICAL_SECTION 只能针对多线程进行锁定,在同一个线程中,是可以进入很多次的. 同一线程可以多次进入临界区. 在测试程序(多线程同时访问CADOAccess类的对象)中,辅助线程不论是 ...
- SQL Server 内存中OLTP内部机制概述(一)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- WORD2003电子签名插件(支持手写、签章)
1.引言 WORD电子签名插件,支持手写.本地电子图章.以及网络图章功能.软件使用VC6,以ATL方式编写,软件小巧精致. 这是我学习ATL的成果,学习过程及程序的编写,前前后后共用了一个多月的时间, ...
- pip 豆瓣镜像使用
pip install -i https://pypi.douban.com/simple/ flask 要用https的 https://pip.pypa.io/en/latest/user_gui ...