0

抱歉,如果之前已经介绍过 - 但我在使用 Rally.ui.combobox.ComboBox 时遇到了一些奇怪的加载行为。

该应用程序所做的(到目前为止)是这样的:

  1. 创建一个 Rally.ui.combobox.IterationComboBox
  2. 选择迭代后,使用过滤到所选迭代的 UserStory 模型填充 Rally.ui.combobox.ComboBox。

单击 UserStory 组合框时,我看到一些奇怪的行为。它最初只显示少数故事(正确地,那些在选定迭代中的故事。

然而,一两分钟后,它会重新绘制自己,然后显示我项目中的所有故事。

JS 控制台显示了一些这样的错误:

  • Uncaught TypeError: Cannot call method 'getCount' of null
  • Uncaught TypeError: Cannot read property 'loading' of null

我怀疑我在故事组合框准备就绪的时间上做错了。所以我添加了一个 onReady 处理程序,但它似乎没有多大帮助。

该行为的视频在这里:

我的代码显示在这里:

<!DOCTYPE html>
<html>
<head>
    <title>CustomApp</title>
    <!--  (c) 2013 Rally Software Development Corp.  All Rights Reserved. -->
    <!--  Build Date: Mon Jul 15 2013 14:23:12 GMT-0600 (Mountain Daylight Time) -->
    <script type="text/javascript" src="https://rally1.rallydev.com/apps/2.0rc1/sdk.js"></script>

    <script type="text/javascript">
        Rally.onReady(function() {

            Ext.define('CustomApp', {
                extend: 'Rally.app.App',
                componentCls: 'app',

                // Stores the Selected Iteration
                selectedIteration: null,

                // Data Store for Stories
                storyStore: null,

                // Stores the Selected Story
                selectedStory: null,

                // Reference to lumenize
                lumenize: null,

                items: [
                    {
                        xtype: 'container',
                        itemId: 'iterationDropdownContainer',
                        columnWidth: 1
                    },
                    {
                        xtype: 'container',
                        itemId: 'storyDropdownContainer',
                        columnWidth: 1
                    },      
                    {
                        xtype: 'container',
                        itemId: 'testResultSummaryContainer',
                        columnWidth: 1
                    }    
                ],

                launch: function() {
                    // Add the iteration dropdown selector
                    this.down("#iterationDropdownContainer").add( {
                        xtype: 'rallyiterationcombobox',
                        itemId : 'iterationSelector',
                        listeners: {
                            select: this._onIterationSelect,
                            scope: this
                        }
                    });

                    // Lumenize
                    this.lumenize = window.parent.Rally.data.lookback.Lumenize; 
                },

                // Callback when an iteration is selected.
                _onIterationSelect : function() {
                    // Store and save the Selected Iteration        
                    var iterationRecord =  this.down('#iterationSelector').getRecord();
                    this.selectedIteration = iterationRecord.data;
                    console.log(iterationRecord);               

                    // Query to get all Stories in Iteration
                    this.storyStore = Ext.create('Rally.data.WsapiDataStore', {
                        model: "User Story",
                        autoLoad: true,
                        fetch: ["ObjectID","Name","Iteration","TestCases"],
                        filters: [
                            {
                                property: 'Iteration.Name',
                                value: this.selectedIteration.Name
                            }
                        ],
                        listeners: {
                            scope : this,
                            load : this._storiesLoaded
                        }
                    }); 
                },

                // Callback when Story Store is loaded
                _storiesLoaded : function(store, data, success) {
                    console.log("_storiesLoaded");
                    console.log(data);

                    if(this.down("#storySelector")) {
                        this.down("#storySelector").destroy();
                    }

                    // Add a story object dropdown selector 
                    this.down("#storyDropdownContainer").add( {
                        xtype: 'rallycombobox',
                        store: this.storyStore,
                        autoLoad: false,
                        disabled: true,
                        itemId : 'storySelector',
                        listeners: {
                            ready: this._storySelectorReady,
                            select: this._onStorySelected,
                            scope: this
                        }
                    }); 
                },

                _storySelectorReady: function(storyCombobox) {
                    storyCombobox.disabled = false;
                },    

                // Callback when a Story has been selected
                _onStorySelected : function() {
                    // Store and save the Selected Iteration        
                    var storyRecord =  this.down('#storySelector').getRecord();
                    this.selectedStory = storyRecord.data;

                    console.log(storyRecord);
                },    

                _showTable : function() {
                    console.log("_showTable");
                }            
            });

           Rally.launchApp('CustomApp', {
               name: 'CustomApp'
           });
        });
    </script>


<link rel="stylesheet" type="text/css" href="src/style/app.css">

</head>
<body></body>
</html>
4

1 回答 1

1

storyStore 会加载两次,一次是在您创建它时,并且组合框还会告诉它在用户打开组合框以选择故事时再次加载。因此,您的商店的负载侦听器被调用了两次,实际上正在创建两个故事组合框。在 Ext 深处的某个地方,它不喜欢这样。

最简单的解决方法是添加single: true到您商店的侦听器:

listeners: {
    scope : this,
    load : this._storiesLoaded,
    single: true
}

但可能更好的方法是将商店设置为创建故事组合框的一部分:

_onIterationSelect : function() {
  // Store and save the Selected Iteration        
  var iterationRecord =  this.down('#iterationSelector').getRecord();
  this.selectedIteration = iterationRecord.data;
  console.log(iterationRecord);               

  this.down("#storyDropdownContainer").add( {
        xtype: 'rallycombobox',
        itemId : 'storySelector',
        storeConfig: {
            model: 'User Story',
            autoLoad: true,
            filters: [{
                  property: 'Iteration.Name',
                  value: this.selectedIteration.Name
            }]
        },
        listeners: {
             ready: this._storySelectorReady,
             select: this._onStorySelected,
             scope: this
        }
  }); 
},
于 2013-09-06T00:44:01.923 回答