Extjs 数据 Model/Store 是否支持任何包装代理构建器方法?

Does Extjs data Model/Store support any wrapper proxy builder method?

我们正在使用 Extjs 5.x 构建基于浏览器的单页应用程序。如果我们使用简单的模型和商店,一切都很好。如果我们尝试使用任何包装器作为代理,它会在 sencha cmd 构建后在运行时生成错误。

文章的简单模型如下:

Ext.define('Pos.model.Article', {
    extend      : 'Ext.data.Model',
    alias       : 'widget.Article',
    idProperty  : 'id', 
    fields      : [
        { name : 'id',         mapping : 'id',         type : 'int'   },
        { name : 'code',       mapping : 'code',       type : 'string'},
        { name : 'name',       mapping : 'name',       type : 'string'},
        { name : 'rate',       mapping : 'rate',       type : 'float' },
        { name : 'expireDate', mapping : 'expireDate', type : 'date'  }
    ],
    proxy      :   {
        type            : 'rest',
        noCache         : true,
        limitParam      : 'limit',
        startParam      : 'start',
        url             : '/pos/article',
        reader          : {
            type            : 'json',
            rootProperty    : 'data',
            totalProperty   : 'total',
            successProperty : 'success',
            messageProperty : 'message',
            implicitIncludes: true
        },
        writer          :{
            type            : 'json',
            writeAllFields  : true 
        },
        simpleSortMode  : true
    }
});

这是文章的简单商店:

Ext.define('Pos.store.Articles', {
    extend       : 'Ext.data.Store',
    model        : 'Pos.model.Article',
    idProperty   : 'id',
    autoLoad     :  false,
    autoSync     :  false,    
    remoteSort   :  true,
    remoteFilter :  true,
    pageSize     :  25,
    proxy        : {
        type            : 'rest',
        noCache         : true,
        limitParam      : 'limit',
        startParam      : 'start',
        url             : '/pos/article/store',
        reader          : {
            type            : 'json',
            rootProperty    : 'data',
            totalProperty   : 'total',
            successProperty : 'success',
            messageProperty : 'message',
            implicitIncludes: true
        },
        writer          :{
            type            : 'json',
            writeAllFields  : true 
        },
        simpleSortMode  : true
    },
    sorters      : [{
        property : 'name', 
        direction: 'ASC'
    }]
});

当我们使用简单模型并将其存储时工作正常。但我们的目标是删除样板代码,因此我们正在尝试构建一些包装方法来删除冗余代码。这是代理构建器的简单包装供您考虑:

var Cki=Cki||{};

;Cki.proxy||(function($){
    var proxy = {
        $package      : 'Cki',
        $class        : 'Cki.proxy',
        resolveUrl    : function(action){
            var ctxPath = '/pos/',
                url     = ctxPath + action;

            return url;
        },
        getReader           : function(){
            var reader  =  {
                    type            : 'json',
                    rootProperty    : 'data',
                    totalProperty   : 'total',
                    successProperty : 'success',
                    messageProperty : 'message',
                    implicitIncludes: true
                };
            return reader;
        },
        getWriter           : function(){
            var writer =  {
                    type            : 'json',
                    writeAllFields  : true 
                };
            return writer;
        },
        getRestProxy        : function(url, noCache){
            url     = (typeof url === 'undefined') ? '' : url;
            noCache = (typeof noCache === 'undefined') ? false : noCache;
            var restProxy    = {
                type            : 'rest',
                noCache         : noCache,
                limitParam      : 'limit',
                startParam      : 'start',
                url             : proxy.resolveUrl(url),
                reader          : proxy.getReader(),
                writer          : proxy.getWriter(),
                simpleSortMode  : true
            };    
            return restProxy;
        }
    };
    $.proxy = proxy;
}(Cki));

一旦代理构建器方法的包装器准备就绪,我们就可以使用它来将代理包装在模型和存储中。这是包装的代理模型:

Ext.define('Pos.model.Article', {
    extend      : 'Ext.data.Model',
    alias       : 'widget.Article',
    idProperty  : 'id', 
    fields      : [
        { name : 'id',         mapping : 'id',         type : 'int'   },
        { name : 'code',       mapping : 'code',       type : 'string'},
        { name : 'name',       mapping : 'name',       type : 'string'},
        { name : 'rate',       mapping : 'rate',       type : 'float' },
        { name : 'expireDate', mapping : 'expireDate', type : 'date'  }
    ],
    proxy      :   Cki.proxy.getRestProxy('article')
});

这是包装好的代理商店:

Ext.define('Pos.store.Articles', {
    extend       : 'Ext.data.Store',
    model        : 'Pos.model.Article',
    idProperty   : 'id',
    autoLoad     :  false,
    autoSync     :  false,    
    remoteSort   :  true,
    remoteFilter :  true,
    pageSize     :  25,
    proxy        :  Cki.proxy.getRestProxy('article/store'),
    sorters      : [{
        property : 'name', 
        direction: 'ASC'
    }]
});

它在运行时产生以下错误:

  1. 主线程上的同步 XMLHttpRequest 已弃用,因为它会对最终用户的体验产生不利影响。如需更多帮助,请查看 https://xhr.spec.whatwg.org/.
  2. http://localhost/pos/static/Ext-all.js 加载资源失败:服务器响应状态为 404(未找到)fetch @Ext-all.js:22
  3. VM42:3 未捕获类型错误:c 不是构造函数

如果不调试就很难找到你的错误,我想即使有了代码也很难..

我建议您更改使用的方法以避免样板代码。

我认为实现此目的的最佳方法是扩展其余代理 class,将所有默认配置放在那里。 然后你只需在你的商店定义中使用你的代理 class,只传递 url(这似乎是模型之间的唯一区别)。

例子

    Ext.define('My.data.proxy.Rest', {
        extend: 'Ext.data.proxy.Rest',
        alias : 'proxy.myrest',
        noCache         : true,
        limitParam      : 'limit',
        startParam      : 'start',
        reader          : {
            type            : 'json',
            rootProperty    : 'data',
            totalProperty   : 'total',
            successProperty : 'success',
            messageProperty : 'message',
            implicitIncludes: true
        },
        writer          :{
            type            : 'json',
            writeAllFields  : true 
        },
        simpleSortMode  : true
    });

在您的商店中,您将拥有

Ext.define('Pos.store.Articles', {
    extend       : 'Ext.data.Store',
    model        : 'Pos.model.Article',
    idProperty   : 'id',
    autoLoad     :  false,
    autoSync     :  false,    
    remoteSort   :  true,
    remoteFilter :  true,
    pageSize     :  25,
    proxy        :  {
         type: 'myrest',
         url: '/pos/article/store',
    },
    sorters      : [{
        property : 'name', 
        direction: 'ASC'
    }]
});