覆盖ExtJS模型吸气剂的最佳实践&制定者

时间:2012-04-27 22:32:58

标签: extjs

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

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

最好的方法是什么?转换,顺便说一句,似乎是一个糟糕的选择。它不是双向的,而且是活的。

1 个答案:

答案 0 :(得分:4)

注意:我没有测试过此代码,因此如果您有疑问,请使用概念并稍后发表评论。

为数据实体定义Ext.data.Model类时(使用Ext.data.Record for Ext JS 3),添加convert函数作为Ext.data.Field属性实例的一部分。如果需要,可以对所有字段执行此操作,但可能不建议这样做。

我是这个框架的新手,所以我不知道怎么做的一件事是在转换函数中使用“this.self”符号,以防你在Model类中扩展另一个类。例如,如果您没有在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中添加了自动获取器和设置器。框架的新版本自动为您的属性添加“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
  }
});