js框架

系统日志和异常的处理②

上一讲我们做了日志与异常的结果显示列表,这一节我们讲要把他应用系统中来。

首先我们在App.Common类库中创建一个通用类ResultHelper,这个类里面写了,获取一个GUID,获取当前时间,处理字符串等操作,虽然我们目前要用到的一个就是获取GUID但是以后我们可能还要用到别的,所以我都把他放进入了

然后在App.Admin创建一个核心文件夹,Core,放入LogHandler这个类是主要是写入日志,避免在每次都要实例化这个类,我把他封装起来,大家一看就知道。

然后修改Controller的Create方法,代码如下一一给出。

  ResultHelper
  LogHandler
  SysSampleController

同时App.Common要引用程序集System.Web

运行添加一条记录,然后打开我们的日志模块,OK,日志记录完成了,有点简单。

接下来是异常,上一讲说到,异常我们放在BLL中处理,然后我们把错误或者异常信息返回到Controller中被日志记录,当然异常他是在BLL层被记录的。

我们需要一个异常的集合类,来记录BLL层和DAL层,有时候DAL也要处理异常,所以我们也要用到ref 引用传递,貌似ref我们很喜欢,呵呵

见代码,在App.Common创建一个异常集合类

  ValidationErrorHelper.cs

我们也要创建一个封装好的异常写入,类似与Log的LogHandler封装但我们放在BLL中,因为我们以后的其他项目的BLL要引用,这一步要考虑到。
在BLL中创建文件夹Core,写入以下类,BLL引用程序集System.Web里面用到了http的一些方法

  ExceptionHander

此异常当处理也异常时候,将在网站根目录下写入一个txt文件。
创建一个全局变量

ValidationErrors errors = new ValidationErrors();

我们要用引用传递,所以要修改IBLL和BLL的Create方法,如下
ISysSampleBLL  :  bool Create(ref ValidationErrors errors, SysSampleModel model);

SysSampleBLL   :

复制代码
 /// <summary>
        /// 创建一个实体
        /// </summary>
        /// <param name="errors">持久的错误信息</param>
        /// <param name="model">模型</param>
        /// <returns>是否成功</returns>
        /// <summary>
        /// 创建一个实体
        /// </summary>
        /// <param name="errors">持久的错误信息</param>
        /// <param name="model">模型</param>
        /// <returns>是否成功</returns>
        public bool Create(ref ValidationErrors errors, SysSampleModel model)
        {
            try
            {
                SysSample entity = Rep.GetById(model.Id);
                if (entity != null)
                {
                    errors.Add("主键重复");
                    return false;
                }
                entity = new SysSample();
                entity.Id = model.Id;
                entity.Name = model.Name;
                entity.Age = model.Age;
                entity.Bir = model.Bir;
                entity.Photo = model.Photo;
                entity.Note = model.Note;
                entity.CreateTime = model.CreateTime;

                if (Rep.Create(entity) == 1)
                {
                    return true;
                }
                else
                {
                    errors.Add("插入失败");
                    return false;
                }
            }
            catch (Exception ex)
            {
                errors.Add(ex.Message);
                ExceptionHander.WriteException(ex);
                return false;
            }
        }
复制代码

修改Controller

复制代码
 [HttpPost]
        public JsonResult Create(SysSampleModel model)
        {
                if (m_BLL.Create(ref errors, model))
                {
                    LogHandler.WriteServiceLog("虚拟用户", "Id:" + model.Id + ",Name:" + model.Name, "成功", "创建", "样例程序");
                    return Json(1, JsonRequestBehavior.AllowGet);
                }
                else
                {
                    string ErrorCol = errors.Error;
                    LogHandler.WriteServiceLog("虚拟用户", "Id:" + model.Id + ",Name:" + model.Name + "," + ErrorCol, "失败", "创建", "样例程序");
                    return Json(0, JsonRequestBehavior.AllowGet);
                }
     
        }
复制代码

 注意:ExceptionHander.WriteException(ex);这里是写入异常信息

OK,你现在可以创建一条新的记录和插入一个ID大于50个字符的记录,让他记录日志和异常了。

js框架_第1张图片

显然我们的失败错误提示已经不符合国情了。我们返回的json格式是0和1我们要返回多个值了,比如1和成功创建,0和失败了啊,这样的2个值怎么办?

controller能把datagrid传过来的东西用类来接受,那么反过来想,js也能把controller发出去的值分解,创建一个序列化的类

在App.Common类库中创建JsonHandler帮助类,里面有2个重载,一个是返回3个值一个是2个值的。

所以当我们要返回订单的数量和总价格的时候,我们将用到类似的手段

  JsonHandler

再次修改Controller的Create

复制代码
  [HttpPost]
        public JsonResult Create(SysSampleModel model)
        {
            if (m_BLL.Create(ref errors, model))
            {
                LogHandler.WriteServiceLog("虚拟用户", "Id:" + model.Id + ",Name:" + model.Name, "成功", "创建", "样例程序");
                return Json(JsonHandler.CreateMessage(1, "插入成功"), JsonRequestBehavior.AllowGet);
            }
            else
            {
                string ErrorCol = errors.Error;
                LogHandler.WriteServiceLog("虚拟用户", "Id:" + model.Id + ",Name:" + model.Name + "," + ErrorCol, "失败", "创建", "样例程序");
                return Json(JsonHandler.CreateMessage(0, "插入失败" + ErrorCol), JsonRequestBehavior.AllowGet);
            }
     
        }
复制代码

修改SysSample的Create的JS部分

复制代码
<script type="text/javascript">
    $(function () {
        $("#btnSave").click(function () {
            if ($("#CreateForm").valid()) {
                $.ajax({
                    url: "/SysSample/Create",
                    type: "Post",
                    data: $("#CreateForm").serialize(),
                    dataType: "json",
                    success: function (data) {
                        if (data.type == 1) {
                            window.parent.frameReturnByMes(data.message);
                            window.parent.frameReturnByReload(true);
                            window.parent.frameReturnByClose()
                        }
                        else {
                            window.parent.frameReturnByMes(data.message);
                        }
                    }
                });
            }
            return false;
        });
    });
    </script>
复制代码

 

js框架_第2张图片

由于时间关系,这一讲就先到这里吧!这一讲其实比较仓促。不懂的留言

你需要继续做的就是在删除,编辑等操作也加入这些的。这点留给大家自己表现吧....

下一讲是全局异常的捕获。

作者: YmNets

实现自己的js框架

两年前写的,现在发出来,也当是一个记录。

我知道贴代码有些人会反对,觉得应该用文字讲细致,但是我觉得用文字我没发用简单的文字来表达,看代码反而更直接,这个是见仁见智的。

很早之前一直用extjs,这个确实非常强大,但是在IE下一直都有一个性能的问题,搞得要让客户换chrome,firefox浏览器才行。

之所以要写自己js框架,原因是觉得自己实现也简单,维护也方便,一些管理应用的项目可以用,网站这些我还是推荐直接使用jquery,毕竟更加简单直接没有那么多可给你重复应用的地方。

可能你要问为什么不用jquery插件,一样可以。但是这些插件代码质量不能保证,风格也是奇形怪状,出了问题还要去看代码,改了之后又跟原作者的有出入,以后同步更加麻烦。

不用jquery插件,但是jquery却是个好东西,解决了浏览器兼容的大问题,所以我这个就是基于jquery来实现的,因为一直喜欢extjs的代码风格,所以如果你使用过extjs的话,使用起来会轻车熟路。

js的继承是原型继承的方式,最开始的时候我确实也用原型的方式来实现,但是后面我发现有些问题,而且理解起来不是太清晰,所以我采用一种简单清晰的方法,写起来是继承但是实际上它只是一个对象。

它同样有着抽象方法,有父类,有重载,有重写等等。

先看一下大概结构如下图:

js框架_第11张图片

现在说下几个重要的地方

首先就是如何定义一个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
define: function  (className, defaultConfig) {
         if  (!wyl.isString(className) || className.isEmpty()) {
             throw  new  Error( "[wyl.define] Invalid class name '"  + className + "' specified, must be a non-empty string" );
         }
         var  namespace_arr = className.split( '.' );
         var  namespace = window;
         var  class_Name = namespace_arr.last();
         wyl.each(namespace_arr, function  (ns) {
             if  (ns == class_Name) { return ; }
             if  (!namespace[ns]) {
                 namespace[ns] = {};
             }
             namespace = namespace[ns];
         });
         if  (namespace[class_Name]) {
             throw  new  Error( '重复定义了'  + className);
         }
         defaultConfig.className = className;
         for  ( var  p in  defaultConfig) {
             if  (wyl.isFunction(defaultConfig[p])) {
                 defaultConfig[p].fnName = p;
             }
         }
         namespace[class_Name] = defaultConfig;
     }

接着就是如何创建一个类的实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
getDefineConfig: function  (namespaces, i, context) {
         if  (context == null ) { return  null ; }
         if  (namespaces.length == i) {
             return  context;
         }
         var  ns = namespaces[i];
         return  wyl.getDefineConfig(namespaces, i + 1, context[ns]);
 
     }
 
     create: function  (className, config) {
         if  (!wyl.isString(className) || className.isEmpty()) {
             throw  new  Error( "[wyl.create] Invalid class name '"  + nsclassName + "' specified, must be a non-empty string" );
         }
         var  namespaces = className.split( '.' );
         var  defineConfig = wyl.getDefineConfig(namespaces, 0, window);
         if  (!defineConfig) { throw  '{0}类型未定义。' .format(className); }
         config = config || {};
         if  (!config.id) { config.id = wyl.newId(); }
         var  instance = {};
         wyl.apply(instance, config, defineConfig);
//继承的关键代码如下
         if  (instance.extend) {
             var  base = wyl.create(instance.extend);
             for  ( var  p in  base) {
                 if  (instance.hasOwnProperty(p)) {
//把父类的方法重新命名赋值到这个实例上
                     if  (wyl.isFunction(instance[p]) && wyl.isFunction(base[p])) {
                         var  baseFnName = instance.extend + '_'  + p;
                         instance[p][ 'baseFnName' ] = instance.extend + '_'  + p;
                         instance[baseFnName] = base[p];
                     }
                 }
                 else  {
                     instance[p] = base[p];
                 }
             }
         }
         instance.initConfig = config;
         if  ( typeof  (instance.init) == 'function' ) {
             instance.init.apply(instance);
         }
         if  (wyl.isFunction(instance.initComponent)) {
             instance.initComponent.apply(instance);
         }
         wyl.each(instance.abstractMethods, function  (methodName) {
             this [methodName] = function  () { throw  this .className + ' has not implement '  + methodName; }
         }, this );
         this .intanceMgr[instance.id] = instance;
         return  instance;
     }

对于所有的类型我定义了一个基类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
wyl.define( 'wyl.object' , {
     initConfig: null ,
     abstractMethods: [],
//ext4.0中调用父类的方法就是这个
     callParent: function  () {
         var  me = this ;
//调用的时候根据之前create里面加入的隐藏信息baseFnName来找到父类的方法并调用它
         var  fnname = me.callParent.caller[ 'baseFnName' ];
         var  fn = me[fnname];
         if  (wyl.isFunction(fn)) {
             fn.call(me);
         }
     },
     addEvents: function  () {
         var  me = this ;
         if  (!wyl.eventMgr[me.id]) { wyl.eventMgr[me.id] = {}; }
         var  myEventMgr = wyl.eventMgr[me.id];
         wyl.each(arguments, function  (eventName) {
             if  (!myEventMgr[eventName]) { myEventMgr[eventName] = []; }
         });
     },
     fireEvent: function  (eventName, prams) {
         var  me = this ;
         var  myEventMgr = wyl.eventMgr[me.id];
         var  listeners = myEventMgr[eventName];
         if  (wyl.isArray(listeners)) {
             wyl.each(listeners, function  (listener) {
                 var  scope = listener.scope ? listener.scope : this ;
                 if  (listener.callback && typeof  (listener.callback) == 'function' ) {
                     listener.callback.call(scope, prams);
                 }
             });
         }
     },
     on: function  (eventName, options) {
         var  me = this ;
         if  (!wyl.eventMgr[me.id]) { wyl.eventMgr[me.id] = {}; }
         var  myEventMgr = wyl.eventMgr[me.id];
         if  (!myEventMgr[eventName]) { myEventMgr[eventName] = []; }
         var  removeIndex = null ;
         wyl.each(myEventMgr[eventName], function  (item, i) {
             var  b = options.callback == item.callback;
             if  (b) { removeIndex = i; }
             return  !b;
         });
         if  (removeIndex && removeIndex > -1) {
             myEventMgr[eventName].removeAt(removeIndex);
         }
         myEventMgr[eventName].push(options);
     },
     destroy: function  () {
         delete  wyl.eventMgr[ this .id];
         delete  wyl.intanceMgr[ this .id];
     },
     init: function  () {
         wyl.apply( this , this .initConfig);
     }
});

界面的控件,我也定义了一个基类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
wyl.define( 'wyl.Component' , {
     extend: 'wyl.object' ,
     containerSelector: null ,
     container: null ,
     abstractMethods: [ 'render' ],
     getContainer: function  () {
         if  ( this .container === null ) {
             this .container = $( this .containerSelector).first();
             if  ( this .container == null ) { throw  '控件必须要设置containerSelector或不存在.' ; }
         }
         return  this .container;
     },
     setContainer: function  (selector) {
         if  ( typeof  (selector) != 'string' ) { throw  '设置container必须是string类型.' ; }
         this .containerSelector = selector;
     },
     getWidth: function  () {
         return  this .getContainer().width() - 2;
     },
     getHeight: function  () {
         return  this .getContainer().height() - 2;
     }
});

大概的思路就是容器会负责分配给下面子控件的容器setContainer,子控件得到自己的容器getContainer,一个控件不需要关系其他控件,只需要控制好自己内部的控件元素就行了。

里面定义了一个抽象方法render,每个控件都必须实现这个方法。容器render的时候,同时如果自己内部有子控件,也render自己内部的子控件。

js框架_第12张图片

源码下载

 
 
分类:  javascript
标签:  wyl js

你可能感兴趣的:(js,wyl)