Rally 集合迭代组合框返回空

Rally 集合迭代组合框返回空,rally,appsdk2,Rally,Appsdk2,我是rally app SDK新手,正在尝试制作教程(来自Youtube和rally网站) 当我试图创建一个iterationComboBox时,对象被创建,但没有值(“没有定义迭代”)。 我试着从github(会话4\u交互式网格)运行这两个视频教程代码 两者都给了我一个空的迭代框 在视频中运行会话3的代码时,我通过创建用户故事存储来获取用户故事数据。我在谷歌上搜索了它,并在这里搜索了副本,但到目前为止没有成功,那么问题出在哪里呢 谢谢 我复制了你发布的代码,两个应用程序都没有做任何更改,而是

我是rally app SDK新手,正在尝试制作教程(来自Youtube和rally网站) 当我试图创建一个iterationComboBox时,对象被创建,但没有值(“没有定义迭代”)。 我试着从github(会话4\u交互式网格)运行这两个视频教程代码

两者都给了我一个空的迭代框

在视频中运行会话3的代码时,我通过创建用户故事存储来获取用户故事数据。我在谷歌上搜索了它,并在这里搜索了副本,但到目前为止没有成功,那么问题出在哪里呢


谢谢

我复制了你发布的代码,两个应用程序都没有做任何更改,而是运行了应用程序,并且在这两种情况下都填充了迭代框。这不是密码。 如果您得到“没有定义迭代”,那么您的项目中可能没有迭代? 从文档中的示例复制的第二个代码中有一个bug,即使填充了迭代组合框,卡也不会显示在板上。DevTools控制台出现错误:“无法读取未定义的属性'refresh'


我有这个应用程序的工作版本

感谢您的回复,我们有很多迭代在我们的项目(s)。我在Rally中从另一台登录到同一工作区和项目的机器上运行应用程序,但没有得到任何结果。我还运行了你的应用程序,但没有结果。我会和我的组织核实,争取支持。谢谢
// Custom Rally App that displays Defects in a grid and filter by Iteration and/or Severity.
//
// Note: various console debugging messages intentionally kept in the code for learning purposes

Ext.define('CustomApp', {
    extend: 'Rally.app.App',      // The parent class manages the app 'lifecycle' and calls launch() when ready
    componentCls: 'app',          // CSS styles found in app.css


    defectStore: undefined,       // app level references to the store and grid for easy access in various methods
    defectGrid: undefined,

    // Entry Point to App
    launch: function() {

      console.log('our second app');     // see console api: https://developers.google.com/chrome-developer-tools/docs/console-api

      this.pulldownContainer = Ext.create('Ext.container.Container', {    // this container lets us control the layout of the pulldowns; they'll be added below
        id: 'pulldown-container-id',
        layout: {
                type: 'hbox',           // 'horizontal' layout
                align: 'stretch'
            }
      });

      this.add(this.pulldownContainer); // must add the pulldown container to the app to be part of the rendering lifecycle, even though it's empty at the moment

       this._loadIterations();
    },

    // create iteration pulldown and load iterations
    _loadIterations: function() {
        this.iterComboBox = Ext.create('Rally.ui.combobox.IterationComboBox', {
          fieldLabel: 'Iteration',
          labelAlign: 'right',
          width: 300,
          listeners: {
            ready: function(combobox) {             // on ready: during initialization of the app, once Iterations are loaded, lets go get Defect Severities
                 this._loadSeverities();
           },
        select: function(combobox, records) {   // on select: after the app has fully loaded, when the user 'select's an iteration, lets just relaod the data
                 this._loadData();
           },
           scope: this
         }
        });

            this.pulldownContainer.add(this.iterComboBox);   // add the iteration list to the pulldown container so it lays out horiz, not the app!
     },

    // create defect severity pulldown then load data
    _loadSeverities: function() {
        this.severityComboBox = Ext.create('Rally.ui.combobox.FieldValueComboBox', {
          model: 'Defect',
          field: 'Severity',
          fieldLabel: 'Severity',
          labelAlign: 'right',
          listeners: {
            ready: function(combobox) {             // this is the last 'data' pulldown we're loading so both events go to just load the actual defect data
                 this._loadData();
           },
            select: function(combobox, records) {
                 this._loadData();
           },
           scope: this                              // <--- don't for get to pass the 'app' level scope into the combo box so the async event functions can call app-level func's!
         }

        });

        this.pulldownContainer.add(this.severityComboBox);    // add the severity list to the pulldown container so it lays out horiz, not the app!
     },

    // Get data from Rally
    _loadData: function() {

      var selectedIterRef = this.iterComboBox.getRecord().get('_ref');              // the _ref is unique, unlike the iteration name that can change; lets query on it instead!
      var selectedSeverityValue = this.severityComboBox.getRecord().get('value');   // remember to console log the record to see the raw data and relize what you can pluck out

      console.log('selected iter', selectedIterRef);
      console.log('selected severity', selectedSeverityValue);

      var myFilters = [                   // in this format, these are AND'ed together; use Rally.data.wsapi.Filter to create programatic AND/OR constructs
            {
              property: 'Iteration',
              operation: '=',
              value: selectedIterRef
            },
            {
              property: 'Severity',
              operation: '=',
              value: selectedSeverityValue
            }
          ];

      // if store exists, just load new data
      if (this.defectStore) {
        console.log('store exists');
        this.defectStore.setFilter(myFilters);
        this.defectStore.load();

      // create store
      } else {
        console.log('creating store');
        this.defectStore = Ext.create('Rally.data.wsapi.Store', {     // create defectStore on the App (via this) so the code above can test for it's existence!
          model: 'Defect',
          autoLoad: true,                         // <----- Don't forget to set this to true! heh
          filters: myFilters,
          listeners: {
              load: function(myStore, myData, success) {
                  console.log('got data!', myStore, myData);
                  if (!this.defectGrid) {           // only create a grid if it does NOT already exist
                        this._createGrid(myStore);      // if we did NOT pass scope:this below, this line would be incorrectly trying to call _createGrid() on the store which does not exist.
                  }
              },
              scope: this                         // This tells the wsapi data store to forward pass along the app-level context into ALL listener functions
          },
          fetch: ['FormattedID', 'Name', 'Severity', 'Iteration']   // Look in the WSAPI docs online to see all fields available!
        });
      }
    },

    // Create and Show a Grid of given defect
    _createGrid: function(myDefectStore) {

      this.defectGrid = Ext.create('Rally.ui.grid.Grid', {
        store: myDefectStore,
        columnCfgs: [         // Columns to display; must be the same names specified in the fetch: above in the wsapi data store
          'FormattedID', 'Name', 'Severity', 'Iteration'
        ]
      });

      this.add(this.defectGrid);       // add the grid Component to the app-level Container (by doing this.add, it uses the app container)

    }

});
Ext.define('CustomApp', {
    extend: 'Rally.app.App',      // The parent class manages the app 'lifecycle' and calls launch() when ready
    componentCls: 'app',          // CSS styles found in app.css

        launch: function() {
        this.iterationCombobox = this.add({
            xtype: 'rallyiterationcombobox',
            listeners: {
                change: this._onIterationComboboxChanged,
                ready: this._onIterationComboboxLoad,
                scope: this
            }
        });
    },

    _onIterationComboboxLoad: function() {
        var addNewConfig = {
            xtype: 'rallyaddnew',
            recordTypes: ['User Story', 'Defect'],
            ignoredRequiredFields: ['Name', 'ScheduleState', 'Project'],
            showAddWithDetails: false,
            listeners: {
                beforecreate: this._onBeforeCreate,
                scope: this
            }
        };

        this.addNew = this.add(addNewConfig);

        var cardBoardConfig = {
            xtype: 'rallycardboard',
            types: ['Defect', 'User Story'],
            attribute: 'ScheduleState',
            storeConfig: {
                filters: [this.iterationCombobox.getQueryFromSelected()]
            }
        };
        this.cardBoard = this.add(cardBoardConfig);       
    },

    _onBeforeCreate: function(addNewComponent, record) {
        record.set('Iteration', this.iterationCombobox.getValue());
    },

    _onIterationComboboxChanged: function() {
        var config = {
            storeConfig: {
                filters: [this.iterationCombobox.getQueryFromSelected()]
            }
        };

        this.cardBoard.refresh(config);
    }
});