Form Demo 注解(ST1)

来源:互联网 发布:数据挖掘行业应用 编辑:程序博客网 时间:2024/05/16 08:13

实例地址


1. app.js

App = new Ext.Application({name:'App',launch: function(){/* * here: App = this * App.views.viewport = new App.views.Viewport(); */this.views.viewport = new App.views.Viewport();//App.views.viewport = new this.views.Viewport();//worx too//usersList and usersForm are component name which can be used by App.views['usersList'] or App.views['usersForm']this.views.usersList = this.views.viewport.down('#usersList');this.views.usersForm = this.views.viewport.down('#usersForm');}});

在app.js中创建2个变量名分别为usersList和usersForm,其namespace为App.views。 比较好的方法是在Viewpor.js中通过Ext.apply创建该两个views,并且加载到viewport的items中去(this.items),具体见(NotesAppMVC/MainView)。


2.Model: User.js

//use App.models.User or Ext.getModel('User') to get this modelApp.models.User = Ext.regModel('User',{fields:[{name: 'id',type: 'int'},{name: 'name',type: 'string'},{name: 'email',type: 'string'},{name: 'phone',type: 'string'}],validations:[{type: 'presence',name: 'name'},{type: 'format',name: 'email',matcher: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,message: 'must be a valid email'}],proxy: {type: 'localstorage',id: 'sencha-users'}});

App.models.User 是类名,通过 new App.models.User()来创建新的instance. 同时id:“User” 可以在使用ModelMgr中使用。

3. Store: Users.js

App.stores.users = new Ext.data.Store({    model: 'User',    autoLoad: true});//Uncaught TypeError: Object myStore has no method 'create'//Uncaught TypeError: Object myStore has no method 'getAt'// App.stores.users = Ext.regStore("myStore",{    // model: 'User',    // autoLoad: true// });

这里App.stores.users是instance, 在List或者controller中的配置项store中,应该写instance名,而不是类名。

另外可以使用regStore为其分配一个id,但是这样就不能使用this.store.getAt(index) 以及 this.store.create(data)


4. Viewport.js

App.views.Viewport = Ext.extend(Ext.Panel,{fullscreen: true,layout:'card',initComponent: function(){Ext.apply(this,{items:[{xtype: 'App.views.UsersList', id: 'usersList'},{xtype: 'App.views.UsersForm', id: 'usersForm'}]});App.views.Viewport.superclass.initComponent.apply(this, arguments);},reveal: function(target) {var direction = (target === 'usersList') ? 'right' : 'left';// console.log("target: " + target);// console.log("direction: " + direction);// console.log("App.views: " + App.views[target]);//target "usersList" is a component name which is definded with this.views."usersList" = in app.jsthis.setActiveItem(App.views[target],{ type: 'slide', direction:direction});}});

viewport.js 是规划一个总视图,并且加上2个子视图:UsersList,UsersForm,这里分配的两个id会覆盖类中定义的所用到的id。默认显示第一个items里的视图。


5. Form.js

5.1 结构规划

先构思一下form的结构,最上面是个titlebar,除了title外,最左面有个返回user List的按钮。最下面是个buttonbar, 最左边有个Delete,最右面有个Save。进一步设想一下,Delete按钮何时该出现(新记录不用delete,只有当修改旧记录时才出现),同样新记录时,save按钮不变,如果是修改旧记录,那么就显示update。最后title也要做相应改变。这里都是通过给component一个id,然后通过down/query来找到component,再进行相关配置项的修改。

App.views.UsersForm = Ext.extend(Ext.form.FormPanel, {defaultInstructions: 'Please enter the information above',initComponent: function(){var titlebar, cancelButton, buttonbar, saveButton, deleteButton, fields;cancelButton = {text: 'cancel',ui: 'back',handler: this.onCancelAction,scope: this};titlebar = {id:'userFormTitlebar',xtype: 'toolbar',title: 'Create user',items: [cancelButton]};saveButton = {id: 'userFormSaveButton',text: 'save',ui: 'confirm',handler: this.onSaveAction,scope: this};//can't call deleteButton.hide()deleteButton = {id: 'userFormDeleteButton',text: 'delete',ui: 'decline',handler: this.onDeleteAction,scope: this};buttonbar = {xtype: 'toolbar',dock: 'bottom',//deleteButton become a button in toolbaritems: [deleteButton, {xtype:'spacer'}, saveButton]};fields = {xtype: 'fieldset',id: 'userFormFieldset',title: 'User details',instructions: this.defaultInstructions,defaults:{xtype: 'textfield',labelAlign: 'left',labelWidth: '40%',required: false,useClearIcon: true,//Deprecated since 2.0, use clearIcon insteadautoCapitalize: false},items:[{name: 'name',label: 'name',autoCapitalize: true//Chrome and Safari on desktop won't use this attribute, so no effect to show off},{xtype:'App.views.ErrorField',fieldname: 'name'},{name: 'email',label: 'email',xtype: 'emailfield'},{xtype: 'App.views.ErrorField',fieldname: 'email'},{name: 'phone',label: 'phone',xtype: 'numberfield'},{xtype: 'App.views.ErrorField',fieldname: 'phone'}]}Ext.apply(this, {scroll: 'vertical',dockedItems:[titlebar, buttonbar],items:[fields],listeners: {//Fires before a Component has been visually activated.beforeactivate: function(){//get button component by using this.down(selector)var deleteButton = this.down('#userFormDeleteButton'),saveButton = this.down('#userFormSaveButton'),titlebar = this.down('#userFormTitlebar'),model = this.getRecord();if(model.phantom) {titlebar.setTitle('Create user');saveButton.setText('create');deleteButton.hide();}else{titlebar.setTitle('Update user');saveButton.setText('update');//this.deleteButton is the class variable, never defined//deleteButton is a variable in initComponent defined.//console.log(deleteButton.id);//worxdeleteButton.show();}},//Fires after a Component has been visually deactivated.deactivate: function(){this.resetForm();}}});App.views.UsersForm.superclass.initComponent.call(this);},

先把各个部件在initComponent中分别定义,然后添加到Ext.apply中。

5.2 函数定义

onCancelAction: function(){Ext.dispatch({controller: 'Users',action: 'index'});},onSaveAction: function(){//console.log("object: " + this.id);                //this reference to usersForm because scope:this (by this save button)                //if scope not set, then this reference to the savebutton not formPanelvar model = this.getRecord();Ext.dispatch({controller: 'Users',action: (model).phantom ? 'save' : 'update',data: this.getValues(),record: model, //Ext.FormPanel.getRecord() returns the Model instance currently loaded into this form(if any)form: this})},onDeleteAction: function(){Ext.Msg.confirm("Delete this user?", "", function(answer){if(answer === 'yes') {Ext.dispatch({controller: 'Users',action: 'remove',record: this.getRecord()});}},this);},showErrors: function(errors){var fieldset = this.down('#userFormFieldset');//console.log("this.fields: " + this.fields.items[0].name);//worx//this.fields has 3 items and each item is afieldthis.fields.each(function(field){//getByField is funk of Ext.data.Errors, return all errors(Array) for the given fieldvar fieldErrors = errors.getByField(field.name);if(fieldErrors.length > 0){var errorField = this.down('#'+field.name+'ErrorField');field.addCls('invalid-field');//Update the content area of a component(errorField). e.g. it shows both in errorfield//var d = new Array({field:'dd',message:'dds'},{field:'dds',message:'ddss'});//errorField.update(d);errorField.update(fieldErrors);//but here only show message of Array fieldErrors//console.log("fieldErrors: " + fieldErrors[0].field);//worx//console.log("fieldErrors: " + fieldErrors[0].message);//worxerrorField.show();}else{this.resetField(field);}}, this);fieldset.setInstructions('Please amend the flagged fields');},resetField: function(field){var errorField = this.down('#'+field.name+'ErrorField');errorField.hide();field.removeCls('invalid-field');return errorField;//need this?},resetForm: function(){//reset all error fieldsvar fieldset = this.down('#userFormFieldset');this.fields.each(function(field){this.resetField(field);},this);fieldset.setInstructions(this.defaultInstructions);//reset all normal fieldsthis.reset();}});Ext.reg('App.views.UsersForm', App.views.UsersForm);

6. List.js

App.views.UsersList = Ext.extend(Ext.Panel, {initComponent: function(){var addButton, titlebar, list;addButton = {itemId: 'addButton',iconCls: 'add',iconMask: true,ui: 'plain',handler: this.onAddAction,scope: this};titlebar = {dock: 'top',xtype: 'toolbar',title: 'Users',items: [{xtype: 'spacer'}, addButton]};list = {xtype: 'list',itemTpl: '{name}',store: App.stores.users,//store: 'myStore',listeners:{scope:this,itemtap:this.onItemtapAction}};Ext.apply(this, {html: 'placeholder',layout: 'fit',dockedItems: [titlebar],items: [list]});App.views.UsersList.superclass.initComponent.call(this);},onAddAction: function(){Ext.dispatch({controller: 'Users',action: 'newForm'});},onItemtapAction: function(obj, index, item, e){Ext.dispatch({controller: 'Users',action: 'editForm',index: index})}});Ext.reg('App.views.UsersList', App.views.UsersList);

7. ErrorField.js

App.views.ErrorField = Ext.extend(Ext.Component, {initComponent: function() {config = {xtype: 'component',id: this.fieldname + 'ErrorField',cls: 'errorfield',tpl: ['<tpl if="values.length > 0">','   <ul>','      <tpl for=".">','          <li>{message}</li>','      </tpl>','   </ul>','</tpl>'],hidden: true};Ext.apply(this, config);App.views.ErrorField.superclass.initComponent.call(this);}});Ext.reg('App.views.ErrorField', App.views.ErrorField);

8. Controller

Ext.regController('Users',{store: App.stores.users,//store: 'myStore',//this.application.views.viewport worx only if this app is created by Ext.regApplictionindex: function(){App.views.viewport.reveal('usersList');},newForm: function(){var model = new App.models.User();App.views.usersForm.load(model);App.views.viewport.reveal('usersForm');},editForm: function(params){var model = this.store.getAt(params.index);App.views.usersForm.load(model);App.views.viewport.reveal('usersForm');},save: function(params){//console.log("before: " + params.record.data.name);//make sure before calling model.validate(), new data has been set into model.params.record.set(params.data);//console.log("after: " + params.record.data.name);var errors = params.record.validate();if(errors.isValid()){//sava data in the store, this.store.create can only be used when App.stores.users = new Ext.data.Store({})//not App.stores.users = Ext.regStore()this.store.create(params.data);//this.store.create(params.record.data);//worx toothis.index();}else{//errors is mixed Object with items which includes each error fieldparams.form.showErrors(errors);}},update: function(params){var tmpUser = new App.models.User(params.data),errors = tmpUser.validate();if(errors.isValid()){                        //bug here, if refresh page, show old record too                        //params.record.set(params.data);//params.record.save();                          params.form.updateRecord(params.model);                          this.store.sync();                          this.index();}else{params.form.showErrors(errors);}},remove: function(params){this.store.remove(params.record);this.store.sync();this.index();}});


原创粉丝点击