Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检查JavaScript对象是否已更改的设计模式_Javascript_Design Patterns - Fatal编程技术网

检查JavaScript对象是否已更改的设计模式

检查JavaScript对象是否已更改的设计模式,javascript,design-patterns,Javascript,Design Patterns,我从服务器上得到一个对象列表 [{name:'test01', age:10},{name:'test02', age:20},{name:'test03', age:30}] 我将它们加载到html控件中供用户编辑。 然后有一个按钮将整个列表批量保存回数据库 我不想发送整个列表,只想发送已更改对象的子集 它可以是数组中任意数量的项。我想做一些类似于Angular之类的框架的事情,在没有对对象属性进行任何更改的情况下标记对象属性,如“pristine”。然后,使用该标志仅向服务器发布非“原始”

我从服务器上得到一个对象列表

[{name:'test01', age:10},{name:'test02', age:20},{name:'test03', age:30}]
我将它们加载到html控件中供用户编辑。 然后有一个按钮将整个列表批量保存回数据库

我不想发送整个列表,只想发送已更改对象的子集


它可以是数组中任意数量的项。我想做一些类似于Angular之类的框架的事情,在没有对对象属性进行任何更改的情况下标记对象属性,如“pristine”。然后,使用该标志仅向服务器发布非“原始”的项,即已修改的项。

无需对原型属性产生兴趣,只要在表单控件元素检测到更改时将其存储在另一个数组中即可

大致如下:

var modified = [];
data.forEach(function(item){
   var domNode = // whatever you use to match data to form control element
   domNode.addEventListener('input',function(){
      if(modified.indexOf(item) === -1){
         modified.push(item);
      }
   });
});

然后在需要保存时将
修改后的
数组发送到服务器下面有一个函数,当提供旧的对象数组和新的对象数组时,该函数将返回已更改的对象数组:

getChanges=function(oldArray,newArray){
风险值变化,i,项目,j,len;
if(JSON.stringify(oldArray)==JSON.stringify(newArray)){
返回false;
}
变化=[];
对于(i=j=0,len=newArray.length;j
例如:

var older=[{name:'test01',age:10},{name:'test02',age:20},{name:'test03',age:30}]
var newer=[{name:'test01',age:10},{name:'test02',age:20},{name:'test03',age:20}]
getChanges(较旧、较新)
(注意test03的年龄现在是20岁)将返回

[{姓名:'test03',年龄:20}]

您只需在客户端导出编辑值的完整列表,将其与旧列表进行比较,然后将更改列表发送到服务器

希望这有帮助

以下是一些想法

  • 使用框架。你说的是有棱角的

  • 使用,尽管Internet Explorer不支持它

  • 与其使用经典属性,不如使用的set/get实现某种更改跟踪

  • 使用getter/setting函数来存储数据而不是属性:
    getName()
    setName()
    。尽管这是
    defineProperty
    现在所做的事情的老方法

  • 每当您将数据绑定到表单元素时,请设置一个特殊属性,指示该属性是否已更改。类似于
    \u\u的内容发生了变化
    。如果对象上的任何属性发生更改,则设置为true

  • 传统的暴力方式:保留来自服务器的原始数据列表,将其深度复制到另一个列表中,将表单控件绑定到新列表中,然后当用户单击“提交”时,将原始列表中的对象与新列表中的对象进行比较,同时将更改的对象取出。可能是最简单的,但不一定是最干净的

  • 对#6的不同理解:为每个始终返回对象原始版本的对象附加一个特殊属性:

  • var myData=[{name:“Larry”,年龄:47}];
    var dataWithCopyOfSelf=myData.map(函数(数据){
    赋值({},数据,{original:data});
    });
    
    //现在使用copyofself将表单绑定到数据。
    为什么不使用Ember.js可观察属性?您可以使用Ember.observer函数获取和设置数据中的更改

    Ember.Object.extend({
      valueObserver: Ember.observer('value', function(sender, key, value,  rev) {
        // Executes whenever the "value" property changes
        // See the addObserver method for more information about the callback arguments
      })
    });
    
    实际上,Ember.object为您执行了很多繁重的操作

    定义对象后,添加一个观察者,如下所示:

    object.addObserver('propertyKey', targetObject, targetAction)
    

    我的想法是对对象键进行排序,并将对象转换为字符串进行比较:

    // use this function to sort keys, and save key=>value in an array
    function objectSerilize(obj) {
      let keys = Object.keys(obj)
      let results = []
      keys.sort((a, b) => a > b ? -1 : a < b ? 1 : 0)
      keys.forEach(key => {
        let value = obj[key]
        if (typeof value === 'object') {
          value = objectSerilize(value)
        }
        results.push({
          key,
          value,
        })
      })
      return results
    }
    // use this function to compare
    function compareObject(a, b) {
      let aStr = JSON.stringify(objectSerilize(a))
      let bStr = JSON.stringify(objectSerilize(b))
      return aStr === bStr
    }
    
    //使用此函数对键进行排序,并将key=>值保存到数组中
    函数对象序列化(obj){
    让keys=Object.keys(obj)
    让结果=[]
    关键字排序((a,b)=>a>b?-1:a{
    let value=obj[key]
    如果(值的类型==='object'){
    值=对象序列化(值)
    }
    结果:推({
    钥匙
    价值
    })
    })
    返回结果
    }
    //使用此函数进行比较
    函数比较对象(a,b){
    让ast=JSON.stringify(objectserialize(a))
    让bStr=JSON.stringify(objectserialize(b))
    返回aStr==bStr
    }
    

    这就是我的想法。

    这将是最干净的,我认为当添加、删除或修改属性时,对象会发出一个事件。 一个简单的实现可能涉及一个带有对象键的数组;每当setter或heck构造函数返回此值时,它首先调用一个返回承诺的静态函数;解析:映射数组中已更改的值:添加的内容、删除的内容或两者都不添加。所以你可以得到(“改变”)等等;返回一个数组。 类似地,每个setter都可以发出一个带有初始值和新值参数的事件。 假设使用了类,您可以很容易地在父泛型类中拥有一个静态方法,该方法可以通过其构造函数调用,因此实际上您可以通过将对象传递给自身或通过super(checkMeProperty)传递给父类来简化大部分过程。

    对于ES6,我们可以使用 要完成此任务:截取对象写入,并将其标记为脏。

    代理允许创建一个处理程序对象,该对象可以捕获、操纵并转发对原始目标对象的更改,基本上允许重新配置其行为。
    我们将采用的陷阱来拦截对象写入操作

    此时,我们可以添加一个不可枚举的属性,例如:
    \u isDirty
    ,用于将对象标记为已修改的脏对象

    当使用陷阱时(在我们的例子中,处理程序的
    set()
    ),不会对Obj应用或反映任何更改