覆盖 ExtJS 模型 getter 和 setter 的最佳实践

Posted

技术标签:

【中文标题】覆盖 ExtJS 模型 getter 和 setter 的最佳实践【英文标题】:best practice for overriding ExtJS model getters & setters 【发布时间】:2012-04-27 22:32:57 【问题描述】:

我想截取模型上的字段获取/设置,以便我可以在值显示之前以及它们存储在模型中之前对其进行转换。在这种情况下,我想在模型中存储 uriencoded 数据,但显示解码后的值。

当我直接覆盖 get/set 方法时,我看到代理正在使用它们将原始数据放入模型中。我不想覆盖那个过程,我什至不知道如何判断是代理加载模型还是 ui。

什么是最好的方法?顺便说一句,转换似乎是一个糟糕的选择。它不是 2-way 和 live。

【问题讨论】:

convert()双向方法。例如,我使用它将十进制颜色代码来回转换为十六进制。 我明白了.. (1) 检索数据时,您是在 ajax 获取之前在服务器上对数据进行编码,然后在将数据显示给最终用户之前对其进行解码? (2)在URL中传递数据时,你编码,然后在你使用数据时在Ext JS中解码? (3) 保存数据的时候,你有Ext JS编码,然后传给服务器解码再保存? 如何转换 2 路函数?在我看来,它只有在某些东西从记录中读取值时才会被调用,即。 myRec.get('field1')。在写操作期间是否有一个等效的转换被调用,即。 myRec.set('field1', '新值')? 【参考方案1】:

注意:我没有测试过这段代码,所以如果你有问题,请稍后使用这些概念和评论。

当您为数据实体定义 Ext.data.Model 类(Ext JS 3 使用 Ext.data.Record)时,添加转换函数作为 Ext.data.Field 属性实例的一部分。如果您愿意,可以对所有字段执行此操作,但可能不推荐。

我是这个框架的新手,所以我不知道如何在转换函数中使用“this.self”表示法,以防您在模型类中扩展另一个类。例如,如果您没有在 Employee 类中定义默认值,并且它继承自另一个类(例如 Employee),但 Employee 构造函数设置了该属性,它将采用超类中定义的值(基编码数据时的类或父类)构造函数。现在,它只是获取 EmployeeDeveloper.dataValue 属性。

Ext.define('EmployeeDeveloper', 
  extend: 'Ext.data.Model',
  fields: [
     name: 'name', type: 'string', defaultValue: 'Paul' ,
     name: 'profession', type: 'string', defaultValue: 'Ext JS developer' ,
     name: 'salary', type: 'float', defaultValue: '95000' ,
     name: 'dataValue', type: 'string',
      convert: function(value, record) 
        // feel free to use value and record parameters in this function
        return encodeData(record.get('dataValue'));  // you may have to use the "value" parameter instead of record.get('dataValue') if referencing the field in it's own convert function (haven't tested)
      
    
  ]
);

var empDev = Ext.create(
  'EmployeeDeveloper', 
  
    name: 'MacGyver',
    dataValue: 'ABC'
  , 
  'MacGyver', 
  123
);

var encodedDataValue = empDev.get('dataValue');

关于转换的注意事项:如果您引用的是在转换函数签名下方定义的字段,代码将不知道它并且无法检索该值。

或者如果您有自定义类但未使用模型类...

今晚我还读到了一些在 Ext JS 中很简洁的东西。他们在 Ext JS 4 中添加了自动 getter 和 setter。新版本的框架会自动为您的属性添加“get”、“set”、“reset”或“apply”前缀,并将“”中属性的第一个字母大写config" 您定义的类的属性。

在常规 javascript 中,它们没有真正的类,但 Sencha 使定义类(使用“define”函数)和实例化用户定义类的对象实例成为可能。

例如,假设您定义了以下类:

Ext.define('Paul.MyClass'), 
  extend: 'Ext.Window',
  config: 
    name: 'Paul'
  
);

如果您像这样创建对象的实例,您将自动访问四个函数。

var win = Ext.create('Paul.MyClass');  // create instance of MyClass object
var myName = win.getName();  // get name
win.setName('MacGyver');  // set name
win.resetName(); // this resets the value back to the default value ('Paul')
win.applyName();  // this calls custom code 
win.show();

我建议用您建议的逻辑覆盖 apply* 方法。然后调用 win.get*();之后获得新的价值。为您计划编码的每个字段设置一个额外的编码字段可能是明智的,这样您就不必在每次访问(获取或设置)代理和/或存储中的数据时都操作属性。

Ext.define('Paul.MyClass'), 
  extend: 'Ext.Window',
  config: 
    name: 'Paul',
    dataValue: 'non encoded value of your data'
  
  applyName: function(title) 
    this.name = this.name + ' ' + title;  // custom logic goes here
  
  applyDataValue: function(encodeKey) 
    // get the encoded data value
    this.self.dataValue = 'encoded data value';  // custom logic goes here
  
);

【讨论】:

我正在使用 ExtJS 4.1 和 Sencha Touch 2.0 - 所以两者都有自动获取器和设置器。关于转换,仍然不确定它对写入有什么帮助,它似乎只对转换读取有用。也许我可以覆盖 getter 和 setter,但在我看来,即使在加载 ie 期间,getter 和 setter 也会被调用。 model.add(newRec) 操作,这对我没有好处。 我还没有在 Ext JS 中编程过.. 这个周末刚做了一些小部件,并且一直在读一本关于这个主题的书。我刚得到一份工作(入门级),我将为当地诊所使用此框架开发数据仓库报告工具,因此我将快速学习。如果我在这本书中看到一些信息或在网上阅读,我会回复你。您可能想在 sencha.com 论坛上发布有关此信息的问题。 model.add(newRec) 没有做什么? 我的问题与 model.add(newRec) 正在做什么有关。它正在调用属性获取器和设置器。我只希望在 UI 访问模型时调用我的 getter 和 setter,而不是在代理加载模型时调用 您能否尝试在 getter 和 setter 中调用 showCallStack,针对您所描述的场景,看看有什么不同或哪些变量不同?此函数将提醒调用堆栈。然后你可以回溯,这样你就可以在你需要的时候破解你的 getter/setter 以在开始时返回(或被忽略),并且只返回字段/属性的当前值而不是编码值。 webdeveloper.com/forum/showthread.php?t=141861

以上是关于覆盖 ExtJS 模型 getter 和 setter 的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能将自动实现的 getter 和 setter 与 List 一起使用? (统一,C#)

EXTJS 本地化(覆盖类)

Lombok 写一个@Data更好还是@Getter+@Setter更好?

javascript 在Javascript中生成可覆盖的getter和setter

ExtJS 4.1 - 覆盖 Ext.LoadMask 的 css

Java bean中布尔类型使用注意