Ajax数据双向数据绑定策略?

2024-01-02

我想 1) 绘制创建表单字段并使用 javascript 对象中的数据填充它们 2) 每当表单字段的值发生变化时更新这些支持对象

第 1 点很容易。我有一些 js 模板系统,我一直在使用它们,效果非常好。

第二点可能需要一些思考。在谷歌上快速搜索“ajax 数据绑定”,发现了一些看起来基本上是单向的系统。它们旨在根据支持 js 对象更新 UI,但似乎没有解决当 UI 发生更改时如何更新这些支持对象的问题。有人可以推荐任何可以为我做这件事的图书馆吗?这是我可以自己写的东西,不会太麻烦,但如果这个问题已经被思考清楚,我宁愿不重复这项工作。

////////////////////// 编辑 /////////////////

我创建了自己的 jquery 插件来完成此任务。这里是。请告诉我它是否有用,以及您是否认为值得将其变得更加“官方”。如果您有问题或疑问,也请告诉我。

/*

    Takes a jquery object and binds its form elements with a backing javascript object. Takes two arguments: the object 
    to be bound to, and an optional "changeListener", which must implement a "changeHappened" method.

    Example: 

    // ============================
    // =     backing object       =
    // ============================

    demoBean = {
        prop1 : "val",
        prop2 : [
            {nestedObjProp:"val"},
            {nestedObjProp:"val"}
        ],
        prop3 : [
            "stringVal1",
            "stringVal12"
        ]
    }

    // ===========================
    // =        FORM FIELD       =
    // ===========================

    <input class="bindable" name="prop2[1].nestedObjProp">


    // ===========================
    // =       INVOCATION        =
    // ===========================

    $jq(".bindable").bindData( 
        demoBean, 
        {changeHappened: function(){console.log("change")}}
    )


*/


(function($){


    // returns the value of the property found at the given path
    // plus a function you can use to set that property
    var navigateObject = function(parentObj, pathArg){
        var immediateParent = parentObj;
        var path = pathArg
            .replace("[", ".")
            .replace("]", "")
            .replace("].", ".")
            .split(".");
        for(var i=0; i< (path.length-1); i++){
            var currentPathKey = path[i];
            immediateParent = immediateParent[currentPathKey];
            if(immediateParent === null){
                throw new Error("bindData plugin encountered a null value at  " + path[i] + " in path" + path);
            }
        }

        return {
            value: immediateParent[path[path.length - 1]],
            set: function(val){
                immediateParent[path[path.length - 1]] = val
            },
            deleteObj: function(){
                if($.isArray(immediateParent)){
                    immediateParent.splice(path[path.length - 1], 1);
                }else{
                    delete  immediateParent[path[path.length - 1]];
                }
            } 
        }

    }

    var isEmpty = function(str){
        return str == null || str == "";
    }

    var bindData = function(parentObj, changeListener){

        var parentObj,
            radioButtons = [];
        var changeListener;
        var settings;
        var defaultSettings = {
            // if this flag is true, you can put a label in a field,
            // like <input value="Phone Number"/>, and the value
            // won't be replaced by a blank value in the parentObj
            // Additionally, if the user clicks on the field, the field will be cleared.
            allowLabelsInfields: true 
        };

        // allow two forms: 
        // function(parentObj, changeListener)
        // and function(settings). 
        if(arguments.length == 2){
            parentObj = arguments[0];
            changeListener = arguments[1]
            settings = defaultSettings;
        }else{  
            settings = $jq.extend(defaultSettings, arguments[0]);
            parentObj = settings.parentObj;
            changeListener = settings.changeListener;
        }

        var changeHappened = function(){};
        if(typeof changeListener != "undefined"){
            if(typeof changeListener.changeHappened == "function"){
                changeHappened = changeListener.changeHappened;
            }else{
                throw new Error("A changeListener must have a method called 'changeHappened'.");
            }
        };
        this.each(function(key,val){
            var formElem = $(val);
            var tagName = formElem.attr("tagName").toLowerCase();
            var fieldType;
          if(tagName == "input"){
            fieldType = formElem.attr("type").toLowerCase();
          }else{
            fieldType = tagName;
          }


            // Use the "name" attribute as the address of the property we want to bind to.
            // Except if it's a radio button, in which case, use the "value" because "name" is the name of the group
            // This should work for arbitrarily deeply nested data. 
            var navigationResult = navigateObject(parentObj, formElem.attr(fieldType === "radio"? "value" : "name"));

            // populate the field with the data in the backing object

            switch(fieldType){

        // is it a radio button? If so, check it or not based on the 
        // boolean value of navigationResult.value
        case "radio":
          radioButtons.push(formElem);
          formElem.data("bindDataPlugin", {navigationResult: navigationResult});
          formElem.attr("checked", navigationResult.value);
          formElem.change(function(){
            // Radio buttons only seem to update when _selected_, not 
            // when deselected. So if one is clicked, update the bound
            // object for all of them. I know it's a little ugly,
            // but it works.
            $jq.each(radioButtons, function(index, button){
              var butt = $jq(button);
              butt.data("bindDataPlugin").navigationResult.set(butt.attr("checked"));
            });
            navigationResult.set(formElem.attr("checked"));           
            changeHappened();
          });
          break;

        case "text":
          // if useFieldLabel is true, it means that the field is 
          // self-labeling. For example, an email field whose 
          // default value is "Enter Email".
          var useFieldLabel = isEmpty( navigationResult.value )
                   && !isEmpty( formElem.val() )  
                   && settings.allowLabelsInfields;
          if(useFieldLabel){
           var labelText = formElem.val();
           formElem.click(function(){
             if(formElem.val() === labelText){
               formElem.val("");
             }
           })
          }else{
           formElem.attr("value", navigationResult.value);
          }
          formElem.keyup(function(){
           navigationResult.set(formElem.attr("value"));
           changeHappened();
          });

          break;

        case "select":
          var domElem = formElem.get(0);
                $jq.each(domElem.options, function(index, option){
                    if(option.value === navigationResult.value){
                        domElem.selectedIndex = index;
                    }
                });
                formElem.change(function(){
                    navigationResult.set(formElem.val());
                })
          break;

        case "textarea":
          formElem.text(navigationResult.value);
          formElem.keyup(function(){
           changeHappened();
           navigationResult.set(formElem.val());
          });
          break;
      }


        });
        return this;
    };

    bindData.navigateObject = navigateObject;

    $.fn.bindData = bindData;

})(jQuery);

有大量的库可以实现您想要的。

对于初学者,您可以使用DWR http://directwebremoting.org/dwr/index.html获得 Ajax 功能。表单字段触发的方法onChange事件应该对相应的支持对象进行 DWR 调用

希望这可以帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ajax数据双向数据绑定策略? 的相关文章

  • 在 Internet Explorer 中使用什么来监视 jscript 内存使用情况

    我们正在调试 GWT 应用程序 在 Firefox 中运行正常 在 IE6 0 中开始运行正常 但一段时间后 它就会崩溃并开始爬行 经过一些测试后 我们怀疑存在一些内存问题 使用了太多内存 内存泄漏等 除了使用taskmanager和pro
  • 如何使用 Playwright 使用选择器查找框架 (iframe)

    我有一个小问题 无法找到使用 Microsoft Playwright 框架的答案 根据您可以使用以下代码获取 iframe const frame page frame frame login 但是如何使用选择器来查找 iframe 并与
  • 自动建议 php 的 ajax

    我有一个 html 表单 php 脚本和 jquery 我需要一个 ajax 代码来从我的 php 脚本中进行自动建议 以下是代码 表单 html
  • 从 HTTP 登录到 HTTPS

    我的网站默认使用 HTTP 我确实有一个启用 HTTPS 的证书 但只有其上的某些区域强制建立安全连接 登录是通过 Ajax 处理的 我想开始使用 SSL 即使请求来自 HTTP 我尝试强制请求的地址具有 HTTPS 并且它完美地回复 然而
  • React autoFocus 将光标设置为输入值的开头

    我有一个受控输入 最初显示一个值 我已将该输入设置为自动聚焦 但当我希望它出现在末尾时 光标出现在输入的开头 我知道这可能是因为自动对焦是在值之前添加的 但我不能 100 确定 在输入字段末尾完成光标初始化的最佳方法是什么 var Test
  • 如何通过单击链接来更改 div 的内容?

    这是我的网页的 修改后的 jsfiddle 它还有很多 而且定位是正确的 与此相反 http jsfiddle net ry0tec3p 1 http jsfiddle net ry0tec3p 1 a href class btn1 st
  • 如何使用角度材料在具有可扩展行的表格中创建嵌套垫表

    我有以下数据 id c9d5ab1a subdomain wing domain aircraft part id c9d5ab1a info mimetype application json info dependent parent
  • 如何使用 Javascript 设置查询字符串

    有没有办法使用 javascript 设置查询字符串的值 我的页面有一个过滤器列表 单击该列表时 它将更改右侧的页内结果窗格 我正在尝试更新 url 的查询字符串值 因此如果用户离开页面 然后单击 后退 按钮 他们将返回到最后一个过滤器选择
  • mongodb 聚合 - 累积字段的不同组值

    如果我有Player表格文件 name String score Int 我有Group文档 其中组代表玩家列表 groupName String players ObjectID 玩家可以属于多个组 我想做一个聚合Player文档 按以下
  • 如何始终将焦点保持在文本框中

    我创建了一个包含两个 div 的 HTML 页面 左侧的 div 页面的 90 是 ajax 结果的目标 右侧的 div 页面的 10 包含一个文本框 该页面的想法是在文本框中输入零件编号 通过条形码扫描仪 并显示与该零件编号匹配的绘图 显
  • 如何计算特定字符在字符串中出现的次数

    我正在尝试创建一个函数来查看数组中的任何字符是否在字符串中 如果是 有多少个 我尝试计算每一种模式 但是太多了 我尝试使用 Python 中的 in 运算符的替代方案 但效果不佳 function calc fit element var
  • LeafleteachLayer函数不会迭代所有Layer

    使用 GeoJSON 数据数组创建一些标记 getJSON GetLocationsServlet function data L geoJSON data onEachFeature onEachFeature addTo mymap G
  • Vaadin 12 将对象传递给 JavaScript 函数:无法对类进行编码

    Vaadin 12 Kotlin 项目 In my myPage html我有JavaScript myObject redirectToCheckout sessionId 1111 2222 所以我需要调用javaScript函数red
  • 聆听 Angular 2 中的元素可见性

    我正在为我的网络应用程序使用 Bootstrap 和 Angular 2 v4 我想监听指令中的元素以了解可见性变化 我的元素有一个可以隐藏其子元素的父元素hidden sm up我需要在每次隐藏或显示时触发一个函数 div hidden
  • 用于选择特定 div 中具有特定类的锚元素的 jQuery 选择器是什么

    我有一些这样的代码 我想选择每个 a 带有类的标签status在 div 中foo div a class status a div 你可以这样做 foo find status a
  • Highcharts jQuery 渲染问题 - 所有浏览器

    我在尝试使用构建堆积柱形图时遇到了一个奇怪的问题高图表 http www highcharts com 当图表呈现时 在您调整浏览器大小之前 不会显示列无论如何 导致图表重绘 我认为 图表的其余部分显示 轴 标题等 但不显示列本身 我在 I
  • 使用 next.js 进行服务器端渲染与传统 SSR

    我非常习惯 SSR 意味着页面得到完全刷新并从服务器接收完整 HTML 的方法 其中根据后端堆栈使用 razor pub other 进行渲染 因此 每次用户单击导航链接时 它只会向服务器发送请求 整个页面将刷新 接收新的 HTML 这就是
  • react-native - 图像需要来自 JSON 的本地路径

    你好社区 我正在react native中开发一个测试应用程序 并尝试从本地存储位置获取图像 我实际在做什么 我将图像直接链接源提供给 var 并在渲染函数中调用此方法 react 0 14 8 react native 0 23 1 np
  • 什么是 WKWebView 中的 WKErrorDomain 错误 4

    fatal error LPWebView encounters an error Error Domain WKErrorDomain Code 4 A JavaScript exception occurred UserInfo 0x7
  • 将数组从 jquery ajax 传递到代码后面

    我必须将二维数组传递给在asp net网页代码后面编写的页面方法我有一个变量objList作为二维数组 我使用以下代码来实现此目的 但没有成功 并且未调用页面方法 脚本语言 function BindTable objList ajax u

随机推荐

  • MVC 中的 CMS 路由

    我正在 php 中创建自己的 MVC 框架 作为学习更高级编程的一种手段 我已经启动并运行了框架 但是我对当前的路由方法有一个问题 我希望该框架支持后端 cms 以补充前端网站 问题是我的路由结构的工作方式如下 mywebsite com
  • 匿名类型中的特殊字符

    我想创建一个变量名称中带有特殊字符的匿名类型 例如我有这个 new status Active 我想要类似的东西 new status Active exists true 这最终会序列化为 JSON 所以我知道我可以使用 JObject
  • 如何使用 SXSSF 写入现有文件?

    我有一个 xlsx 文件 其中包含多个包含不同数据的工作表 所有sheet中一张sheet需要容纳近10万行数据 数据需要使用java配合poi编写 这对于 SXSSFWorkbook 来说似乎非常快速和简单 我只能在内存中保留 100 行
  • where 子句中的多个“in”语句需要相互匹配

    我有一个很长的查询 本质上是以下查询的扩展 update property lease period set scca uplift 110 scca notes code 21006 where suite id CCBG08 and l
  • Laravel 服务提供者和服务容器

    在 Laravel 中访问查询 我们使用DB facades DB select 来自阿兰斯托姆网站http alanstorm com binding objects as laravel services http alanstorm
  • 从日志文件中提取特定行的数据

    我希望从长日志文件中的表中提取并打印特定行 它看起来像这样 XSCALE VERSION July 4 2012 4 Jun 2013 Author Wolfgang Kabsch Copy licensed until 30 Jun 20
  • Leaflet.js:WMS 图层样式

    我有一个 Leaflet javascript Web 应用程序 它使用 WMS 来调用 GeoServer 返回的对象是Geometry加上属性 虽然几何图形 多边形 可以像美国的县一样渲染良好 但我需要根据县人口使县图层显示不同的颜色
  • 使用具有严格内容安全策略的 Angular Material

    我正在使用 Angular 6 和 Angular Material 6 开发企业应用程序 现在我必须为一个具有非常严格的 CSP 的新客户构建项目 那就是 内容安全策略 default src self 该政策无法修改 我搜索了以前的答案
  • 异步/等待 Lambda

    我有一个奇怪的问题 结合 async await 使其工作 我创建了一个小程序 它基本上应该处理每个操作的 try catch internal static void HandledAction Action action Info in
  • 将 arrayList 数据加载到 JTable 中

    我正在尝试通过名为的方法设置项目FootballClub到目前为止还好 但后来我从中创建了一个 arrayList 但不知何故找不到一种方法将此信息存储到 JTable 中 问题是我找不到设置固定行数的方法 这是我的代码 起始联赛类别 im
  • 如何使用 Django Usurena“mugshot”模板变量

    我正在尝试在 Django 网站中使用 Userena 但我似乎不知道如何使用模板标签来显示照片 我尝试了以下方法来输出图像标签中的 URL img src and img src 有人有一些见解吗 Thanks 基于 alican 的答案
  • 如何使用 openssl 创建包含 CRL 分发点的证书?

    我在使用 openssl 创建包含用于测试的 crl 分发点的 x509 证书时遇到问题 我检查了文档并找到了用于此目的的配置设置 crlDistributionPoints 不幸的是 openssl 始终生成 x509 版本 1 证书 而
  • 使用 ColdFusion 从 SQL 数据库抓取长文本,输出被截断

    我有一个 SQL 数据库ntext保存页面内容的字段 我正在使用 ColdFusion 查询信息并将其传递到表单中 该表格使用ckeditor来处理这个特定的字段 该字段目前包含大约4000个字符 在 ckeditor 窗口中查看时 似乎缺
  • 1l 表示长整型,1f 表示浮点型,1d 表示双精度型,那么字节呢?

    1l 表示长整型 1f 表示浮点型 1d 表示双精度型 那么字节呢 long l 1l float f 1f double d 1d byte b 1 相当于什么byte 它存在吗 不 没有后缀可以附加到数字文字上以使其成为byte See
  • 不透明内容到底意味着什么?

    Here http docs oracle com javase 7 docs api java nio file attribute BasicFileAttributes html isRegularFile 28 29我们有描述isR
  • PHP-PDO 获取以列作为索引、以列作为值的结果集[重复]

    这个问题在这里已经有答案了 您好 我有一个具有以下结构的表 date price 2014 02 19 34 2014 02 20 30 2014 02 21 28 目前 PDO FETCH ASSOC 返回一个格式如下的关联数组 arra
  • 如何在Android中每2个字符后连接特殊符号作为冒号

    我想连接或附加特殊字符作为冒号 String 中每 2 个字符之后 例如 原始字符串如下 String abc AABBCCDDEEFF 连接或附加冒号后如下 String abc AA BB CC DD EE FF 所以我的问题是我们如何
  • preg_replace、str_replace 和 substr_replace 在特殊条件下不起作用

    我有以下代码 这段代码找到字符串中的所有 html 标签 并将它们替换为 0 1 2 等 至少这是有意的 但不起作用 str some text a href review review a here a class abc href ab
  • 无法使用 ID 在服务器上进行更新

    我正在更新表单 并且想使用 id 在服务器上发出更新请求 我的模型是 var CampaignEditModel Backbone Model extend urlRoot http localhost 3033 campaign upda
  • Ajax数据双向数据绑定策略?

    我想 1 绘制创建表单字段并使用 javascript 对象中的数据填充它们 2 每当表单字段的值发生变化时更新这些支持对象 第 1 点很容易 我有一些 js 模板系统 我一直在使用它们 效果非常好 第二点可能需要一些思考 在谷歌上快速搜索