现在的位置: 首页 > 综合 > 正文

12、ExtJs——数据代理-proxy

2018年02月05日 ⁄ 综合 ⁄ 共 8119字 ⁄ 字号 评论关闭

数据代理proxy是进行数据读写的主要途径,通过代理操作数据的CRUD

每一步操作全会得到唯一的Ext.data.Operation实例,它包含了所有的请求参数,

数据代理proxy目录结构

Ext.data.proxy.Proxy  代理类的根类(它分为客户端(client)代理和服务器代理(Server))
      Ext.data.proxy.Client 客户端代理
            Ext.data.proxy.Memory  普通的内存代理
            Ext.data.proxy.WebStorage   浏览器客户端存储代理
                  Ext.data.proxy.SessionStorage  浏览器级别代理
                  Ext.data.proxy.LocalStorage    本地化的级别代理(跨浏览器)
      Ext.data.proxy.Server   服务器端代理
            Ext.data.proxy.Ajax     异步加载的方式
                  Ext.data.proxy.Rest  一种特殊的Ajax
            Ext.data.proxy.JsonP 跨域交互的代理——跨域是有严重的安全隐患的,extjs的跨域也是需要服务器端做相应的配合
            Ext.data.proxy.Direct  命令
            3+方式的代理

REST指Representation State Transfer(有时写作ReST),表示性状态转移,其要求无状态、客户端-服务器、具有缓存机制的通信协议——实际上是使用HTTP协议。

REST应用使用HTTP请求来POST数据(创建和/或更新)、读取数据(例如进行查询)、删除数据。
REST使用HTTP来进行CRUD(Create/Read/Update/Delete)操作。

一、内存代理的使用

Ext.onReady(function(){
	//Ext.data.proxy.Memory  内存代理   它的 proxy: memory
	//Memory的configs有:
	//batchActions、batchOrder、data、enablePaging、listeners、model、reader、write
	//其中data表示内存数据的来源,model表示代理哪个对象(哪个model)
	
	Ext.define('User',{
		extend:'Ext.data.Model',
		fields:[
		{name:'name',type:'string'},
		{name:'age',type:'int'}
		]
	});
	//不用create方法,直接用代理Proxy来创建对象数据
	var userData = [
		{name:'name_fdsafs',age:3},
		{name:'nane_yyyy',age:54}
	];
	//创建model的代理类
	var memoryProxy = Ext.create('Ext.data.proxy.Memory',{
		data:userData,
		model:'User'
	});
	//做CRUD
	
	userData.push({name:'new name',age:90});
	//Update
	memoryProxy.update(new Ext.data.Operation({
		action:'update',
		data:userData
	}),function(result){},this);
	
	//Read
	memoryProxy.read(new Ext.data.Operation(),function(result){
//		console.info(result);
		var datas = result.resultSet.records;
		Ext.Array.each(datas,function(model){
//			console.info(model);
//			alert(Ext.encode(model));
			alert(model.data.name);
		})
	});
	
	
});

这个实例在Extjs下运行是有问题的,主要是update出错,出错信息:

Uncaught TypeError: Cannot read property 'length' of null          ext-all-dev.js:102469
Ext.define.updateOperation                                         ext-all-dev.js:102469
Ext.define.update                                                  ext-all-dev.js:102507
(anonymous function)                                               proxy_memory.js:28
(anonymous function)                                               ext-all-dev.js:16067
fire                                                               ext-all-dev.js:16022
Ext.apply.readyEvent.readyEvent.fire                               ext-all-dev.js:16280
Ext.apply.fireReadyEvent                                           ext-all-dev.js:16380
(anonymous function)                                               ext-all-dev.js:3335

对于这个实例的更新,他做的好像也不对,感觉成了插入,更新后数据条数应该不变的,只是记录数据有变化,看一下源代码,更新用的是Ext.data.proxy.Memory的update方法:下面是源代码

update: function() {
        this.updateOperation.apply(this, arguments);
    },

也就是说调用了updateOperation,这个源码:

/**
     * @private
     * Fake processing function to commit the records, set the current operation
     * to successful and call the callback if provided. This function is shared
     * by the create, update and destroy methods to perform the bare minimum
     * processing required for the proxy to register a result from the action.
     */
    updateOperation: function(operation, callback, scope) {
        var i = 0,
            recs = operation.getRecords(),
            len = recs.length;
            
        for (i; i < len; i++) {
            recs[i].commit();
        }
        operation.setCompleted();
        operation.setSuccessful();
        
        Ext.callback(callback, scope || this, [operation]);
    }

首先是执行operation.getRecords(),operation就是Ext.data.Operation,即:

new Ext.data.Operation({
action:'update',
data:userData
})

是一个Ext.data.Operation实例,它的getRecords()方法:看文档的API:

Returns the records associated with this operation.
For read operations the records as set by the Proxy will
be returned (returns null if the proxy has not yet set the records). For create, update, and destroy
operations the operation's initially configured records will be returned, although the proxy may modify these records' data at some point after the operation is initialized.

Returns

返回的是Ext.data.Model对象数组,这里关键是说明的第一句:Returns the recordsassociated
with this operation
.

返回跟这个operation相关的记录集,也即一组Model对象,这里就有疑惑了,这些Model都有哪些呢?我们new的时候,并没有配置model,只有一个action和一个data,那么是memoryProxy这个代理关联的model吗,如果是,就应该是User,????,然后是User.commit();也就是Ext.data.Model的commit方法,看API说明:

[silent],
[modifiedFieldNames]
 )

Usually called by the Ext.data.Store which owns the model instance.
Commits all changes made to the instance since either creation or the last commit operation.

Developers should subscribe to the Ext.data.Store.update event
to have their code notified of commit operations.

源代码:

/**
     * Usually called by the {@link Ext.data.Store} which owns the model instance. Commits all changes made to the
     * instance since either creation or the last commit operation.
     *
     * Developers should subscribe to the {@link Ext.data.Store#event-update} event to have their code notified of commit
     * operations.
     *
     * @param {Boolean} [silent=false] Pass `true` to skip notification of the owning store of the change.
     * @param {String[]} [modifiedFieldNames] Array of field names changed during sync with server if known.
     * Omit or pass `null` if unknown. An empty array means that it is known that no fields were modified
     * by the server's response.
     * Defaults to false.
     */
    commit : function(silent, modifiedFieldNames) {
        var me = this;

        me.phantom = me.dirty = me.editing = false;
        me.modified = {};

        if (silent !== true) {
            me.afterCommit(modifiedFieldNames);
        }
    },

这里出现错误的原因是)
Ext.data.Model[]返回的是undefine

Ext.data.Operation的getRecords方法源代码:

 /**
     * Returns the {@link Ext.data.Model record}s associated with this operation.  For read operations the records as set by the {@link Ext.data.proxy.Proxy Proxy} will be returned (returns `null` if the proxy has not yet set the records).
     * For create, update, and destroy operations the operation's initially configured records will be returned, although the proxy may modify these records' data at some point after the operation is initialized.
     * @return {Ext.data.Model[]}
     */
    getRecords: function() {
        var resultSet = this.getResultSet();
        return this.records || (resultSet ? resultSet.records : null);
    },
/**
     * Returns the ResultSet object (if set by the Proxy). This object will contain the {@link Ext.data.Model model}
     * instances as well as meta data such as number of instances fetched, number available etc
     * @return {Ext.data.ResultSet} The ResultSet object
     */
    getResultSet: function() {
        return this.resultSet;
    },

通过这两个方法,getRecords返回的是Ext.data.Model[],这个返回值要么是operation的records,或者是通过getResultSet()返回的值,而getResultSet()又是返回resultSet,这个属性,按照说明是Returns the ResultSet object (if set by the Proxy),是被代理设置进operation中的。

这个对象将包含model实例以及元数据,such as number of instances fetched, number available etc,这句怎么翻译,什么意思搞不太懂,(一个数字实例,数字可用等????)

proxy的设置,不知道,基础太差,看不下去了,暂停了。

二、localstorage,使用cookie,会保存在机器cookie中,只要不清cookie,数据都保存着

Ext.onReady(function(){
	Ext.define('User',{
		extend:'Ext.data.Model',
		fields:[
			{name:'name',type:'string'}
		],
		proxy:{
			type:'localstorage', //使用cookie,不关闭浏览器,每次刷新,增加,关闭浏览器,不清cookie,依然保存上次数据
			id:'id11111'
		}
	});
	//我们使用store来初始化数据
	var store = new Ext.data.Store({
		model:User
	});
	store.add({name:'cdsaf'});
	store.sync();
	store.load();
	var msg = [];
	store.each(function(rec){
		msg.push(rec.get('name'));
	});
	alert(msg.join('\n'));
	
});

三、sessionstorage,使用session,关闭浏览器,以前增加的数据就丢失了,从头开始

Ext.onReady(function(){
	Ext.define('User',{
		extend:'Ext.data.Model',
		fields:[
			{name:'name',type:'string'}
		],
		proxy:{
			type:'sessionstorage',              //使用session,不关闭浏览器,每次刷新,增加,关闭浏览器,从头开始
			id:'id11111'
		}
	});
	//我们使用store来初始化数据
	var store = new Ext.data.Store({
		model:User
	});
	store.add({name:'cdsaf'});
	store.sync();
	store.load();
	var msg = [];
	store.each(function(rec){
		msg.push(rec.get('name'));
	});
	alert(msg.join('\n'));
	
});

四、ajax方式

Ext.onReady(function(){
	Ext.define('User',{
		extend:'Ext.data.Model',
		fields:[
			{name:'name',type:'string'}
		]
	});
	
	var ajaxProxy = new Ext.data.proxy.Ajax({
		url:'base/user.jsp',
		model:'User',
		reader:'json',
		limitParam:'indexLimit'
	});
	
	ajaxProxy.doRequest(new Ext.data.Operation({
		action:'read',
		limit:2,
		start:1,
		sorters:[
			new Ext.util.Sorter({
				property:'name',
				direction:'ASC'
			})
		]
	}),function(o){
		var text = o.response.responseText;
		alert(Ext.JSON.decode(text)['name']);
	});
	
});

base/user.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
		response.getWriter().write("{name:'cdf'}");
%>

对于ajax方式,通过调试器,可以看到发出了请求:

Request URL:

http://localhost:8080/EasyExt/base/user.jsp?_dc=1411647308507&start=1&indexLimit=2&sort=%5B%7B%22property%22%3A%22name%22%2C%22direction%22%3A%22ASC%22%7D%5D

我们创建的Ext.data.operation的各配置项,在这里看到了,像:start:1,limit:2与limitParam:‘indexLimit结合形成indexLimit=2,sort

五、JsonP跨域:

Ext.onReady(function(){
	Ext.define('User',{
		extend:'Ext.data.Model',
		fields:[
			{name:'name',type:'string'}
		],
		proxy:{
			type:'jsonp',
			url:'http://192.168.1.30:81/user.php'
		}
	});
	
	//jsonP,跨域
	var user = Ext.ModelManager.getModel('User');
	user.load(1,{
		scope:this,
		success:function(model){
			alert(model.get('name'));
		}
	});
});

user.php:

<?php
echo "Ext.data.JsonP.callback1({name:'cdcdcd'})";

可以通过调试工具的network,看出各配置项是如何组成提交条件的

抱歉!评论已关闭.