ExtJS网格面板的Ajax问题

3

我代码中有一个网格面板:

Ext.create('Ext.grid.Panel', {
        id : 'frPanel-' + interfaceId,
        store : frStore,
        columns : [
                {
                    text : 'Sequence',
                    dataIndex : 'ruleId',
                    menuDisabled : true
                },
                {
                    text : 'Source',
                    dataIndex : 'source',
                    renderer : function(value, metaData) {
                        var newValue = convertObjValue(value);
                        if (newValue.match(/[-]+/i)) {
                            metaData.tdAttr = 'data-qtip="'
                                    + networkStore(value) + '"';
                        }
                        return newValue;
                    }
                },
// paging bar at the bottom
        dockedItems : [ {
            xtype : 'pagingtoolbar',
            store : frStore, // same store GridPanel is using
            dock : 'bottom',
            displayInfo : true
        } ],
height : 300,
        width : '100%',
        forceFit : true,
        renderTo : 'frContainer-' + interfaceId
    });

以下是我拥有的辅助函数:

// To get the value after 2nd colon for object and object-group
function convertObjValue(value) {
    var result;
    var exp = /.*?:.*?:(.*)/i;
    var newValue = value;

    if ((result = exp.exec(value)) != null) {
        if (result.index === exp.lastIndex) {
            exp.lastIndex++;
        }
        newValue = result[1];
    }
    return newValue;
}

商店:

function networkStore(value) {

//var store = Ext.create('Ext.data.Store', {
var store = new Ext.data.Store({
    model : 'networkModel',
    autoLoad : {
        timeout : 60000
    },
    proxy : {
        type : 'ajax',
        url : networkObjsURL + "&" + Ext.urlEncode({
            'peId' : value
        }),
        reader : {
            type : 'json',
            idProperty : 'objValue'
        },
     }
});
var hoverOutput = "";

if(store.data.length > 0){
store.data.items.forEach(function(item) {
    hoverOutput += item.data.objectValue + "</br>";
});
}
console.log(hoverOutput);
return hoverOutput;

最后但同样重要的是模型:

Ext.define('networkModel', {
    extend : 'Ext.data.Model',
    fields : [ {
        name : 'objectValue'
    } ]
});

现在有一个问题。问题是,如果我在浏览器的store中不放置断点,则值不会显示在qtip中。我猜这是因为grid panel在ajax响应后没有等待store响应返回。有人可以帮我找到解决此情况的方法吗?
谢谢提前。

普通的小伙伴们需要一点帮助! - user9517536248
还有其他人想试试吗?我现在已经陷入这个问题中很长一段时间了。 - user9517536248
请为此问题创建一个 Fiddle。 - Renganathan M G
你应该尽量将代码精简到最少,以获取仅需的最小代码以重现问题。没有人想要浏览与手头问题无关的应用程序中的一些随机代码。 - hon2a
ExtJS的版本是哪个?5吗?你代码中的控制流对我来说很奇怪。为什么你间接地在render函数中创建存储(直接在networkStore中多次创建)?尽管如此,存储正在异步获取数据。所以你必须等待/回调结果(或者例如使用Future/Promise API)。此外,你应该在frStore存储中拥有网格所需的任何必要数据(你将其传递给网格)。你可以利用模型中的数据关联,这样你就可以在模型中创建新字段或者只是在render函数中使用该关联。 - rzymek
2个回答

0

我在评论中询问您使用的ExtJS版本,但没有得到回应,所以我假设您正在使用ExtJS 5。

对于我的代码来说,控制流程有些奇怪。 为什么您间接在render函数中创建store(直接在networkStore中)多次?

尽管如此,store是异步获取数据的,所以您必须等待/回调结果(或者可以使用Future/Promise API)。此外,您应该在frStore store中包含网格所需的任何数据(传递给网格)。您还可以利用模型中的数据关联,或者在模型中创建带有convert函数的新字段,并在render函数中使用关联/字段的值。

让我向您展示其中一种方法(简单的方法)。

ExtJS不喜欢在render函数内部修改记录,因此我们准备了一个具有必要的qtip值的模型。

我假设您可以提前加载networkStore的数据(autoload: true),但这只是为了简单起见,您稍后可以更改它,例如使用remoteFilter和回调函数。

您没有展示frStore和底层模型的定义,因此我将使用FrStoreFrModel作为类名。

Ext.define('FrModel', {
  extend: 'Ext.data.Model',
  // ...
  fields: [
    // source field
    // ...
    /** qtip value **/
    {
      name: 'qtip',
      type: 'string',
      convert: function (value, record) {
        var result = '';
        // below code is from your render function with modifications
        if (record.get('rendered_source').match(/[-]+/i)) {
          result = 'data-qtip="'
             + networkStore(record.get('source')) + '"';
        }
        return result;
      },
      depends: ['source', 'rendered_source']
    },
    /** rendered source **/
    {
      name: 'rendered_source',
      type: 'string',
      convert: function (value, record) {
        var newValue = convertObjValue(record.get('source'));
        return newValue;
      },
      depends: ['source']
    }
  ]
  // ...
}

在那之后,render函数变得简单了:

// ...
{
  text : 'Source',
  dataIndex : 'rendered_source', // this will allow users to sort & filter this field by the values which are displayed
  renderer : function(value, metaData, record) {
      metaData.tdAttr = 'data-qtip="'
        + record.get('qtip') + '"';
    }
    return value;
  }
},
// ...

你也可以需要一个NetworkStore,你可以将它放在单独的文件中:(我更喜欢在模型中使用代理/模式,但我已经使用了你的代码)

Ext.create('Ext.data.Store', { // using Ext.create is better
    model : 'networkModel',
    storeId: 'networkStore', // registering store in  Ext.data.StoreManager in order to get later this store by Ext.getStore(<store_id>)
    autoLoad : true,
    proxy : {
        type : 'ajax',
        url : networkObjsURL, // we load all records but I mentioned earlier that you can change this
        reader : {
            type : 'json',
            idProperty : 'objValue'
        },
     }
});

我在 netowrkModel 中添加了 peId 字段,因为我们之后想要查询存储。

Ext.define('networkModel', {
    extend : 'Ext.data.Model',
    fields : [
      {
        name: 'objectValue'
      },
      {
        name: 'peId',
        type: 'int'
      }
    ]
});

最后一部分是 networkStore 函数:
function networkStore(value) {
  var store = Ext.getStore('networkStore');
  var records = store.query('peId', value, false, true, true);
  var hoverOutput = "";

  if (records.length > 0) {
    records.each(function(item) {
      hoverOutput += item.get('objectValue') + "</br>";
    });
  }

  console.log(hoverOutput);
  return hoverOutput;
}

PS. 我没有测试上面的代码。

然而,我认为正确的解决方案使用关联。我建议你阅读this doc

你应该了解诸如模式、代理、关联等概念。

当你通过peIdFrModelNetworkModel连接起来时,你就不需要NetworkStore,并且可以基于该关联在convert函数中构建qtip


我正在使用4.2.1 @rzymek。 - user9517536248

0

你尝试过设置吗?

autoLoad:false 

然后类似于:

store.load({
    callback: function(records, operation, success) {
        if (success == true) {
            //do your stuff
            var hoverOutput = "";

            if(store.data.length > 0){
            store.data.items.forEach(function(item) {
                hoverOutput += item.data.objectValue + "</br>";
            });
            }
            console.log(hoverOutput);
            return hoverOutput;
        } else {
            // the store didn't load, deal with it
        }
    }
    // scope: this,
});

由于您的断点允许您查看数据,我认为您正确地假设这是延迟问题。由于Ext是异步的,在继续处理之前,它不会等待ajax调用完成。回调函数将帮助您管理此问题,因为它将在ajax返回时被调用。

我对Ext仍然相当新,但至少这是我的理解。希望它能有所帮助,或者至少指引您走向正确的方向。

编辑一下,因为我提醒过,有时在成功内部使用return会使调试变得困难等等。因此,您还可以尝试将成功更改为调用另一个函数,并让该函数进行处理,只需记住作用域即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接