Ext JS 4:视图中的getter和setter

时间:2013-09-23 15:41:35

标签: oop extjs extjs4 getter-setter

我一直在考虑这个问题,我似乎无法找到合理的解决方案。我想要做的是在我的视图中为textfield /它的值创建getter / setter。我意识到首选的Ext JS方式是在控制器中使用引用并以此方式获取它,但这对我来说并不是非常面向对象的。我还必须包装这些getter和setter因为我想在getter返回undefined时输出一条消息。我想做的是创建我自己的getter / setter或以某种方式覆盖默认的getter / setter。以下是我想要实现这一目标的一些方法。

我以为我可以使用config {},但这似乎只适用于我想要定义的变量。然后我想以某种方式使用id,但社区似乎对这是否是一个好的做法存在分歧。这导致我目前的解决方案...包装。这是我的代码:

  

登录窗口

Ext.define('MyApp.view.LoginWindow', {
    extend: 'Ext.window.Window',
    alias: 'widget.loginWindow',
    autoShow: true,
    closable: false,
    border: 0,
    plain: true,
    allowBlank: false,
    title: "Enter your username",
    modal: true,
    config: {
        buttons: [{
            text: "Ok"
        }],
        items: [{
            xtype: 'textfield',
            fieldLabel: 'Username',
            id: 'loginUserInput',
            name: 'loginUserInput',
            msgTarget: 'under',
            validator: function(value) {
                if (Ext.isEmpty(value)) {
                    return "You need to enter a username.";
                }
                return true;
            }
        }]
    },

    constructor: function(config) {
        this.callParent(config);
    },

    getButton: function() {
        console.log('here');
    }
});
  

myController的

Ext.define('MyApp.controller.Chat', {
    extend: 'Ext.app.Controller',

    requires: [
        'Views.ChatModule.view.LoginWindow'
    ],

    refs: [{
        ref: 'loginWindow',
        selector: 'loginWindow',
        xtype: 'loginWindow',
        autoCreate: true
    }, {
        ref: 'loginUserInput',
        selector: '#loginUserInput'
    }],

    init: function() {
        // The events controller oversees
        this.control({
            'loginWindow button[text="Ok"]': {
                'click': this.onSubmitLoginWindow
            }
        });
    },

    getLoginUserInputValue: function() {
        var loginUserInput = this.getLoginUserInput();
        if (loginUserInput) {
            var username = loginUserInput.getValue();
            if (username) {
                console.log(username);
            } else {
                console.warn("username is undefined");
            }
        }
        console.warn("loginUserInput is undefined");
    },

    onSubmitLoginWindow: function(button, event, eOpts) {
        this.getLoginUserInputValue();
    }
});

这是有效的,我意识到这是一个非常挑剔的事情,但是在控制器中有吸气剂感觉不对。如果它在Window中,我觉得它会更像面向对象。但是,如果我把它放在窗口中,我相信我唯一的选择是依靠id或在Window的initComponent中手动创建文本字段 - 这将涉及在那里保存文本字段的引用,但这似乎有点低效......因为我也必须打电话给doLayout。

重申一点,我希望在窗口中拥有getter / setter,我正在寻找一种快速的方法来引用它,类似于控制器引用对象的方式。我相信主要的答案是使用id并在窗口中调用Ext.ComponentQuery.query('#loginUserInput'),但我想知道是否有更好的方法...比如覆盖自动生成的getter / setters或者为输入值添加一个简单的getter / setter。

来自Sencha forums的交叉发布。

修改

我想我对自己想要的东西有点不清楚。作为一个更一般的陈述,我不想在控制器中干扰与我的视图相关的所有事物,而是将它全部存储在视图本身中,其中包括getter / setter之类的东西。其中一个getter / setter恰好是loginUserInput getter。

使用模型是一个有趣的想法,但我觉得这对单例值来说将是一个很大的开销。我基本上在LoginWindow视图中寻找像Java setters/getters这样的东西......希望像Java一样简单(或接近)。

在视图中包含(封装)它的想法使控制器更清洁,如果我删除视图,我也删除它的功能,所以我不必去寻找它的功能控制器......所有我不得不担心的是删除引用(这应该是最小的)。

3 个答案:

答案 0 :(得分:1)

我认为您正在寻找的“OO”方式是使用Ext.data.Model表单。如果查看Ext.form.Basic,您可以使用方法来操作模型(称为记录),并使用视图的值获取对象。所以你需要:

  1. 创建表单时,使用loadRecord()将表单绑定到模型。
  2. 您可以随时使用getValues()检索表单字段的值。
  3. 提交表单时,请使用getRecord()getValues()同步您的记录。

  4. Ext.define('MyApp.model.Login',{
      fields : [{
        name: 'username',
        type: 'string'
      },{
        name: 'password',
        type: 'string'
      }]
    });
    
    Ext.define('MyApp.controller.Login',{
      ...
      refs : [{
        selector: 'window form',
        ref: 'formPanel'
      }],
      ...
      openForm : function() {
        //load your form and then bind the new record
        var formPanel = this.getFormPanel(), //Ext.form.Panel
            form = formPanel.getForm(); //Ext.form.Basic
    
        form.loadRecord(Ext.create('MyApp.model.Login'));
    
      },
      save : function() {
        //get the values in the view
        var form = this.getFormPanel().getForm(),
            vals = form.getValues(),
            record = form.getRecord();
    
        console.log(vals); //see the object representation of your view here
        record.set(vals); //update your model
    
        //do whatever you need with your model
    
      }
      ...
    });
    

    当您需要保存表单数据时,这是一个很好的示例。在登录中,我认为您可以直接使用getValues()而不将其绑定到Ext.data.Model

答案 1 :(得分:0)

我不太确定你要跟你说实话要解决什么问题。

如果您不喜欢在窗口中按下按钮的控制器,您可以让视图定义中的按钮处理程序触发控制器可以侦听的自定义事件。使用fireEvent method。顺便说一句,initConfig是一种建议你的观点的方法。如果您愿意,可以将其分解为方法,“此”引用可用,并且是实例化的View组件。

如果您需要在视图中查找内部组件,可以使用up / downnextSiblingquery提供的许多方法。

For Components:
    • Ext.getCmp(id)
    • Ext.ComponentQuery.query()
    • up() 
    • down() 
    • nextSibling() 
    • previousSibling()
    • child()
    • previousNode()
plus various find.. Methods

修改

我想我明白你的意思是吸气鬼和制定者。 Ext表单具有字段查找器,可以轻松获取并将数据设置为单个字段。请参阅以下问题:Best way to access adjacent components / fieldsEXT.JS getting a list of items from a fieldset

也像塞尔吉奥所说的那样,在表单上有getRecord getValues和setRecord方法来处理数据绑定。多数民众赞成。

<强> EDIT2

最佳出发点指南,显示清晰和claen MVC模式以及表单处理。 http://docs.sencha.com/extjs/4.1.3/#!/guide/application_architecture

答案 2 :(得分:0)

我的想法是这样的:

...
items: [],
constructor: function(config) {
  this.loginUserInput = Ext.create('Ext.form.field.Text', {
    fieldLabel: 'Username',
    id: 'loginUserInput',
    name: 'loginUserInput',
    msgTarget: 'under',
    validator: function(value) {
      if (Ext.isEmpty(value)) {
        return "You need to enter a username.";
      }
      return true;
    }
  });
  this.items.push(this.loginUserInput);
  this.callParent(config);
},

getLoginUserInput: function() {
  var loginUserInput = this.loginUserInput;
  if (!loginUserInput) {
    console.warn("LoginWindow::getLoginUserInput: loginUserInput is undefined");
  }
  return loginUserInput;
}

因此,我不是让Ext做它的魔法,而是我自己实例化对象,然后允许我存储它的引用,所以我可以在我的getter中轻松访问它。我只是想知道这是否会造成任何性能损失。它似乎并没有那么糟糕......它实际上似乎有点好,因为我没有通过它的ID引用这个对象,我不必去寻找它当我需要它时。