使用Rally.ui.combobox.ComboBox进行奇怪的加载行为

时间:2013-07-15 20:37:43

标签: javascript rally

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

所有应用程序(到目前为止)都是这样:

  1. 创建Rally.ui.combobox.IterationComboBox
  2. 选择迭代后,使用过滤到Selected Iteration的UserStory模型填充Rally.ui.combobox.ComboBox。
  3. 点击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>
    

1 个答案:

答案 0 :(得分: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
        }
  }); 
},