zoukankan      html  css  js  c++  java
  • Knockot JS 数字输入插件

    我将它放在了在GitHub上面,希望有高手一起来帮助完善它,这里附上网址:

     之前写过XML技术在界面生成中的简单应用的文章,后来由于一直很忙,就没有再写。但是东西已经可以用了, 附上截图给大家预览下,等自己不那么紧张的时候,再接着跟大家分享,这里先行道歉!

    再附上一TabPanel为例子的XML代码:

    复制代码
    1 <Tab ID="tab1" Cols="12" Offset="0">
    2   <TabItem Key="tabitem1" LabelText="选项卡一">
    3     <TextBox ID="tabitemtextbox1" LabelWidth="10" Cols="3" Offset="0" LabelText ="文字输入一:" Value="$root.text"/>
    4     <TextBox ID="tabitemtextbox2" LabelWidth="100" Cols="3" Offset="0" LabelText ="文字输入二:" Value="$root.text" NotWripRow="true"/>
    5     <TextBox ID="tabitemtextbox3" LabelWidth="100" Cols="3" Offset="0" LabelText ="文字输入三:" Value="$root.text" NotWripRow="true"/>
    6     <TextBox ID="tabitemtextbox4" LabelWidth="100" Cols="3" Offset="0" LabelText ="文字输入四:" Value="$root.text" NotWripRow="true"/>
    7   </TabItem>
    8 </Tab>
    复制代码

    然后这里是关于操作的定义方式,分为服务器端和客户端操作,其中客户端操作不需要额外手写代码,服务器端也是ajax交互的。也贴出来给大家探讨下(注释部分表示可以那样嵌套定义操作):

    复制代码
     1 <Operations>
     2   <Operation ID="saveData">
     3     <ServerOperation Handler="SaveChanges" FinishAlert="'保存数据'">
     4       <!--<ServerOperation Handler="SaveChanges" FinishAlert="'Second'"></ServerOperation>
     5         <ClientOperation Handler="Confirm" Para="'From client'"></ClientOperation>
     6         <ClientOperation Handler="Information" Para="'From client'"></ClientOperation>
     7         <FailbackOperation>
     8           <ClientOperation Handler="Error" Para="'From client'"></ClientOperation>
     9         </FailbackOperation>-->
    10     </ServerOperation>
    11   </Operation>
    12   <Operation ID="changeValue">
    13     <ClientOperation Handler="ChangeValue" Para="'$root.mCourseList[0].Name', $root.mCourseList()[0].Desc" />
    14   </Operation>
    15   <Operation ID="changeValue1">
    16     <ClientOperation Handler="ChangeValue" Para="'$root.mCourseList[*].Name', $root.mCourseList()[1].Desc" />
    17   </Operation>
    18   <Operation ID="openWindow">
    19     <ClientOperation Handler="OpenWindow" Para="'window1'" />
    20   </Operation>
    21 </Operations>
    复制代码

    当然,OpenWindow有关于Window的定义,如下:

    复制代码
    1 <PopWindow Height="100" Width="100" IsEnable="true" IsVisible="true" ID="window1" Title="这是个窗口" >
    2   <TableContainer>
    3     <DataGrid Rows="6" SelectColumnName ="isSelected" SelectMode="multi" ID="datagrid1" DataSource="$root.mCourseList">
    4       <Column BindFieldKey="Name" Header="名称" Tip="This is tip"/>
    5       <Column BindFieldKey="Desc" Header="描述" Tip="This is tip"/>
    6     </DataGrid>
    7   </TableContainer>
    8 </PopWindow>
    复制代码

    看看Rhyme定义的客户端操作类库, 例如ChangeValue,解析'$root.mCourseList[*].Name'这个表达式的代码还算有些价值, 当然,还不太完善:

    复制代码
     1 ChangeValue: function (args, successCallBack, failureCallBack) {
     2     var _$root, _$data, _event, _target, _assignTo, _from, _dataContext, _statements, _assignmentInContextByStatementsWithValue;
     3 
     4     // Context params.
     5     _$root = args.$root;    // Root context of view model.
     6     _$data = args.$data;    // Current context of view model.
     7     _event = args.event;    // Event from dom or jQuery .
     8     _target = args.target;    // Source element of event.
     9 
    10     // The change where target.
    11     _assignTo = args.params[0];
    12     // The new value.
    13     _from = ko.utils.unwrapObservable(args.params[1]);
    14 
    15     // When the target was observable object, Assignment new value to it.
    16     if (typeof (_assignTo) === 'function') {
    17         _assignTo(_from);
    18     } else if (typeof (_assignTo) === 'string') {
    19         //  The list of statements need to parse.
    20         _statements = _assignTo.replace(/\[\*\]/g, '.*').replace(/\[\d\]/g, function (s, t) { return '.' + s.replace(/[^\d]/g, ''); }).split('.');
    21         _assignmentInContextByStatementsWithValue = function (dataContext, statements, newValue, currentStatementIndex) {
    22             var _currentContext = dataContext,
    23                 _currentContextLength,
    24                 _currentStatementIndex = currentStatementIndex,
    25                 _currentStatement,
    26                 _indexStatement,
    27                 _totalStatements = statements.length;
    28 
    29             // Syntactic analysis.
    30             for (var i = _currentStatementIndex; i < _totalStatements; i++) {
    31                 _currentStatement = statements[i];
    32 
    33                 if (_currentStatement === '$root' || _currentStatement === '$data') {
    34                     continue;
    35                 } else if (/^\d+$/.test(_currentStatement)) { // Match index statement.
    36                     _indexStatement = parseInt(statements[i]);
    37 
    38                     if (i === _totalStatements - 1) {
    39                         _currentContext[_indexStatement](newValue);
    40                     } else {
    41                         _assignmentInContextByStatementsWithValue(_currentContext[_indexStatement], statements, newValue, i + 1);
    42                     }
    43                 } else if (_currentStatement === '*') { // Match every item.
    44                     _currentContextLength = ko.utils.unwrapObservable(_currentContext).length;
    45                     for (var j = 0; j < _currentContextLength; j++) {
    46                         debugger;
    47                         if (i === _totalStatements - 1) {
    48                             _currentContext[j](newValue);
    49                         } else {
    50                             _assignmentInContextByStatementsWithValue(_currentContext[j], statements, newValue, i + 1);
    51                         }
    52                     }
    53                 } else { // In normal case.
    54                     if (i === _totalStatements - 1) {
    55                         dataContext[_currentStatement.replace(/\(\)/g, '')](newValue);
    56                     } else {
    57                         _currentContext = ko.utils.unwrapObservable(dataContext[_currentStatement.replace(/\(\)/g, '')]);
    58                     }
    59                 }
    60             }
    61         };
    62 
    63         if (_statements[0].search("\\u0024data") != -1) {
    64             _dataContext = _$data;
    65         } else {
    66             _dataContext = _$root;
    67         }
    68 
    69         _assignmentInContextByStatementsWithValue(_dataContext, _statements, _from, 0);
    70     }
    71 }
    复制代码

    还有Rhyme 为操作的定义自动生成了相应的操作代码:

    复制代码
     1 (function(){ $(function(){initViewModel('PageLoaded', 'Evaluation');}); })();
     2 
     3 var saveData = function ($root, $data, event, target){window.appViewModel.doAction('SaveChanges','保存数据' , function (viewModel, response) {  }, function (xhr) {  });}
     4 
     5 var changeValue = function ($root, $data, event, target){
     6     ClientEventHandlers.ChangeValue({ $root: $root, $data: $data, event: event, target: target, params: ['$root.mCourseList[0].Name', $root.mCourseList()[0].Desc] }, function(){  }, function(){  });
     7 }
     8 
     9 var changeValue1 = function ($root, $data, event, target){
    10     ClientEventHandlers.ChangeValue({ $root: $root, $data: $data, event: event, target: target, params: ['$root.mCourseList[*].Name', $root.mCourseList()[1].Desc] }, function(){  }, function(){  });
    11 }
    12 
    13 var openWindow = function ($root, $data, event, target){
    14     ClientEventHandlers.OpenWindow({ $root: $root, $data: $data, event: event, target: target, params: ['window1'] }, function(){  }, function(){  });
    15 }
    复制代码

    由于Rhyme比较懒惰,所以ViewModel定义了个通用的,当然,如果你不懒惰,定义N个慢慢玩玩后再决定是否也会学Rhyme偷懒吧。(:以后会慢慢完善:

    复制代码
     1 var ViewModel = function (url, pageCode, initAction) {
     2 
     3     var self = this;
     4 
     5     self.url = url;
     6     self.pageCode = ko.observable(pageCode);
     7 
     8     self.loadData = function (dataHandler, successMsg, successCallBack, failureCallBack) {
     9         var _data = {};
    10         debugger;
    11         
    12         if (typeof (dataHandler) === 'function') {
    13             _data = dataHandler(ko.toJS(self));
    14         }
    15 
    16         $.ajax({
    17             url: self.url,
    18             data: { pageCode: _data.pageCode, actionName: _data.actionName, "datasource": ko.toJSON(_data) },
    19             type: "POST",
    20             dataType: 'json',
    21             error: function (xhr) {
    22                 if (typeof (failureCallBack) === 'function') {
    23                     try {
    24                         failureCallBack(self, xhr);
    25                         MessageCenter.fromXhr(e);
    26                     } catch (e) {
    27                         MessageCenter.fromException(e);
    28                     }
    29                 }
    30             },
    31             success: function (response) {
    32                 if (successMsg) {
    33                     MessageCenter.success(successMsg);
    34                 }
    35 
    36                 if (typeof (successCallBack) === 'function') {
    37                     try {
    38                         successCallBack(self, response);
    39                     } catch (e) {
    40                         MessageCenter.fromException(e);
    41                     }
    42                 }
    43             }
    44         });
    45         
    46         return self;
    47     };
    48 
    49     // Call service.
    50     self.doAction = function (actionName, successMsg, successCallBack, failureCallBack) {
    51         debugger;
    52         self.loadData(function (model) {
    53             model.actionName = actionName;
    54 
    55             return model;
    56         }, successMsg, successCallBack, failureCallBack);
    57     };
    58 
    59     //self.saveChanges = function () {
    60     //    self.doAction("SaveChanges", successMsg, function (viewModel, response) {
    61     //        debugger;
    62     //        ko.mapping.fromJS(response, {}, viewModel);
    63     //    });
    64     //};
    65 
    66     self.bind = function(element) {
    67         if(element) {
    68             ko.applyBindings(self);
    69         } else {
    70             ko.applyBindings(self);
    71         }
    72     };
    73     
    74     (function(){
    75         if(typeof(initAction) === 'function') {
    76             try {
    77                 initAction(self);
    78             } catch(ex) {
    79                 // init error
    80             }
    81         }
    82     })();
    83 };
    复制代码

    还有为了兼容万恶的IE, 不得不用JS来调整组件大小。Rhyme的布局是支持响应式布局的。当然,也是基于Bootstrap的。

    复制代码
     1 (function () {
     2     $(function () {
     3         var resizeControls = function (forVisible, containerSelector) {
     4             var selectorTemplate = 'input[type="text"]{forVisible},input[type="password"]{forVisible},select{forVisible},textarea{forVisible}';
     5             var selector = '';
     6 
     7             if (forVisible === true) {
     8                 selector = selectorTemplate.replace(/{forVisible}/g, ':visible');
     9             } else {
    10                 selector = selectorTemplate.replace(/{forVisible}/g, '');
    11             }
    12 
    13             var $resizeControl = $(selector, containerSelector);
    14             var totalControlForResize = $resizeControl.length;
    15             for (var i = 0; i < totalControlForResize; i++) {
    16 
    17                 var currentControl = $resizeControl.get(i),
    18                     $currentControl = $(currentControl),
    19                     $parent = $currentControl.parents('.control-group'),
    20                     $label = $parent.children('.control-label');
    21                 if ($label && $label.get(0)) { $currentControl.width($parent.get(0).offsetWidth - $label.get(0).offsetWidth - 15); }
    22                 else {
    23                     $currentControl.width($parent.get(0).offsetWidth - 15);
    24                 }
    25             }
    26         };
    27 
    28         resizeControls(true, '.controls');
    29 
    30         window.onresize = function () {
    31             resizeControls(true, '.controls');
    32         };
    33 
    34         $('[data-toggle="tab"]').live('click', function () {
    35             var container = $(this).attr('href');
    36             resizeControls(false, container);
    37         });
    38 
    39         $('[data-toggle="details"]').live('click', function () {
    40             var container = $(this).attr('data-toggle-target');
    41             window.setTimeout(function () { resizeControls(false, container); }, 10)
    42         });
    43     });
    44 })();
    复制代码

    Rhyme 也为布局提供了模版,类似母版页,当然,用的是HTML,生成后的也是纯HTML,由于服务于企业内部系统,所以没有对SEO做任何考虑。

    View Code

    Rhyme由于工作比较忙,所以难得抽出时间整理东西,接下来要是再有时间,会把那个语法解析的完善下,争取让Knockout中让人头疼的括号语法消失。Rhyme初步的想法是在绑定数据前对原有表达式语法重新解析,这样需要括号的地方就可以解析的时候在用代码插入了。有哪位有更好的想法请求分享一下。(:

    Rhyme接下来的源代码会托管到GitHub,也会在博客园放下载,大家共同学习,也多帮我找找Bug,提点不足,在这里先行谢过了。

     
     
     
  • 相关阅读:
    SQL PASS 北京2013年6月15日活动照片集
    XML约束文档DTD
    内存管理之虚拟页式分配
    设备驱动中异步通知编程
    王家林 云计算分布式大数据Hadoop实战高手之路第七讲Hadoop图文训练课程:通过HDFS的心跳来测试replication具体的工作机制和流程
    安装配置netanalyzer/netsnmp3.5.7_rc1
    理解Java对象序列化——Serializable接口
    世界500强高频逻辑推理智力面试题(二)
    2column left navigation 中遇到的问题
    Visual Studio 2010 无法打开 源 文件 "iostream.h"
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2881532.html
Copyright © 2011-2022 走看看