Sencha Touch 2:数据视图和后退按钮不起作用

时间:2014-07-19 16:03:55

标签: sencha-touch-2

我在组件Ext.dataView.DataView中有一个推文列表。单击列表项,它会打开一个容器,其中包含推文的详细信息。这个投币器由工具栏(带标题和后退按钮),推文信息和包含推文用户位置的地图组成。后退按钮应返回列表但不起作用。如何解决?

这是一段代码:

'TweetList'

Ext.define('TwitterSearch.view.TweetList', {    extend: 'Ext.dataview.DataView',
xtype: 'tweetlist',
requires: [
    'TwitterSearch.view.TweetListItem',
    'Ext.plugin.PullRefresh',
    'Ext.plugin.ListPaging',
    'TwitterSearch.view.contact.Show'
],


config: {
    ui           : 'timeline',
    defaultType  : 'tweetlistitem',
    allowDeselect: false,
    useComponents: true,
    emptyText: 'No tweets found.',
    itemTpl: ['TwitterSearch.view.contact.Show'],


    plugins: [
        'pullrefresh',
        {
            type: 'listpaging',
            autoPaging: true
        }
    ],


    items: [
        {
            docked: 'top',
            xtype : 'toolbar',
            hidden: true,
            ui    : 'searchbar',
            items: [
                {
                    xtype: 'button',
                    ui   : 'back',
                    text : 'Searches'
                }
            ]
        }
    ]
},
initialize: function(obj, eOpts) {
    this.callParent();
  }});

'显示别名TweetDetail'

Ext.define('TwitterSearch.view.contact.Show', {
extend : 'Ext.Container',
xtype : 'contact-show',
requires: [ 'Ext.Map'],


config : {
    store: 'Tweet',
    title : 'Information',
    baseCls : 'x-show-contact',
    layout : 'vbox',
    items : [
             {
             xtype: 'toolbar',
             docked: 'top',
             title: 'Tweets Detail',

             items: [
                     {
                         xtype: 'button',
                         text: 'Back',
                         ui: 'back',
                         id: 'tweetDetailBackButton'
                     }
                 ]





            },{
                id : 'contenuto',
                tpl : [ 
                        '<div class="header">',
                        '<div class="avatar"><img src="../resources/images/default_profile_6_bigger.jpeg" /></div>',             
                        '<h3>Nome: {nomeutente}</h3>',
                        '<h4>Tweet: {tweet} </h4>',
                        '</div>',

                        '<p>Descrizione:{descrizione}</p>',
                        '<p>Lingua:{lingua}</p>',
                        '<p>Et&#225:{eta}</p>',
                        '<p>Nazione:{country}, Citt&#225:{city}</p>',
                        //'<p>Nazione:{country}</p>',            
                        //'<p>Citt&#225:{city}</p>',
                        '<p>Latitudine:{latitude},Longitudine:{longitude}</p>',
                        //'<p>Id Utente:{id_utente}</p>',
                        //'<p>Id Luogo:{id_luogo}</p>',

                        ].join('')
            }, {    

                xtype: 'map',
                id: 'dettaglio-map',
                flex: 1,
                mapOptions: {
                    zoomControl: true,
                    zoomControlOptions: {
                      style: google.maps.ZoomControlStyle.DEFAULT
                    },
                    navigationControl: true,
                    navigationControlOptions: {
                        style: google.maps.NavigationControlStyle.DEFAULT
                    },
                    panControl: true,
                    rotateControl: true,
                    streetViewControl: false,
                    mapTypeControl: true,
                    zoom: 12
                },
                listeners: {
                    painted: function(map) {
                        record = map.getData();
                    },

                }
            }
        ],
        record: null
},


updateRecord: function(newRecord) {
    if (newRecord) {
        this.down('#contenuto').setData(newRecord.data);
        this.down('#dettaglio-map').setData(newRecord.data);

        this.down('map').setMapCenter({
            latitude: newRecord.data.latitude,
            longitude: newRecord.data.longitude
        });  

    var map = this.down('map').getMap();
        var marker = new google.maps.Marker({
            position: position = new google.maps.LatLng (newRecord.data.latitude,newRecord.data.longitude),
            map: map,
            title : 'Position = ' + position.toString()
        });
        var infowindow = new google.maps.InfoWindow({
            content: marker.title
        });



    marker.setMap(map);  

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.open(map, marker);
    });

    }
}});

'MainSearch'由SearchBar,SearchList和TweetList'

组成
Ext.define('TwitterSearch.view.MainSearch', {
extend: 'Ext.Container',
xtype : 'mainsearch',


requires: [
    'TwitterSearch.view.SearchBar',
    'TwitterSearch.view.SearchList',
    'TwitterSearch.view.TweetList'
],


config: {
    fullscreen: true
},
initialize: function(obj, eOpts) {
    this.callParent();
  }});

和控制器......

Ext.define('TwitterSearch.controller.SearchController', {
extend: 'Ext.app.Controller',


config: {
    refs: {
        main: {
            selector  : 'mainview',
            xtype     : 'mainview',
            autoCreate: true
        },
        searchBar: 'searchbar',
        searchList: 'searchlist',
        tweetList: 'tweetlist',
        searchField: 'searchbar > searchfield',
        showContact: 'contact-show',    
    },


    control: {
        searchField: {
            keyup: 'onSearch'
        },


        tweetList: {
            itemtap: 'onTweetTap'
        },


        searchList: {
            select: 'onSearchSelect',
            itemswipe: 'onSearchSwipe'
        },


        'searchlist searchlistitem button': {
            tap: 'onSearchDelete',
        },

        'contact-show button[ui=back]': {
            tap: 'onBackButtonTap'
        }

        }
},


launch: function() {
    Ext.getStore('SearchesStore').load({
        callback: this.onSearchesStoreLoad,
        scope: this
    });
},


/**
 * Called when the searchesStore has been loaded from localStorage. If it is NOT a phone, it will select one of the searches
 * from the list, now that it is loaded.
 * We don't want to select a search when it is loaded on a phone, as it would trigger the tweetList view to display.
 */
onSearchesStoreLoad: function() {
    var search = Ext.getStore('SearchesStore').getAt(0);
    if (!search) {
        this.doSearch("%%");
    }
},



/**
 * Called when a search is selected from the searchList. It sets the store of the tweetList to the tweets() store of the selected
 * search isntance. If the device is a phone, we set the active item to the tweetList. If it is now, we just ensure the tweetList
 * is visible
 */
onSearchSelect: function(list, search) {
    var store = search.tweets();


    this.getTweetList().setStore(store);
    store.load();
},


/**
 * Called when an item in the searchList is swiped. It will show the delete button in the swiped item.
 */
onSearchSwipe: function(dataview, index, target) {
    if (Ext.getStore('SearchesStore').getCount() < 2) {
        return;
    }


    //set the currentDeleteButton so we know what is it to hide it in the listener below
    this.currentDeleteButton = target.getDeleteButton();
    this.currentDeleteButton.show();


    //add a listener to the body, so we can hide the button if the user taps anywhere but the button.
    Ext.getBody().on('tap', this.onBodyTap, this);
},


/**
 * Called when the user taps on the body. Hides the delete button and removes the listener from the body.
 */
onBodyTap: function(e) {
    if (this.currentDeleteButton) {
        this.currentDeleteButton.hide();
    }


    //remove the listener
    Ext.getBody().un('tap', this.onBodyTap, this);
},


/**
 * Called when a user taps on an item in the tweetList. This is used to check if the element the user tapped on is a hashtag.
 * If it is a hashtag, we get watchever that hashtag is and call {@link #doSearch} with it.
 * We could possibly extend this to users, too.
 */
onTweetTap: function(list, index, target, record, e) {
    target = Ext.get(e.target);


    if (target && target.dom && target.hasCls('hashtag')) {
        this.doSearch(target.dom.innerHTML);
    }
    else if (!this.showContact) {
        this.showContact = Ext.create('TwitterSearch.view.contact.Show');
    }
    this.showContact.setRecord(record);


    if (!this.showContact.getParent()) {
        //Ext.Viewport.removeAll(true,true);
        Ext.Viewport.removeAt(0);

        Ext.Viewport.add(this.showContact);
    }


    this.showContact.show();
},

onContactShow: function() {
    Ext.getCmp('viewport').getLayout().getAnimation().setReverse(false);
},



/**
 * Called when a use taps the delete button on a searchList item
 */
onSearchDelete: function(button, e) {
    var item   = button.getParent(),
        search = item.getRecord();


    this.fireAction('destroy', [search, button], 'doDestroy');
},


/**
 * Removes a specified search record from the searches store. The tablet controller subclass has some additional
 * logic to select the nearest saved search
 */
doDestroy: function(search, button) {
    var store = Ext.getStore('SearchesStore');


    store.remove(search);
    store.sync();
    button.hide();
},


/**
 * Called on the keyup event of the search field. If the enter/return key was pressed, it will fire the search action.
 */
onSearch: function(field, e) {
    var keyCode = e.event.keyCode,
        searchField = this.getSearchField();


    //the return keyCode is 13.
    if (keyCode == 13) {
        //fire the search action with the current value of the searchField
        this.fireAction('search', [searchField.getValue()], 'doSearch');

    }
},


/**
 * Called with the search action above. Searches twitter for a specified search term or record
 */
doSearch: function(search) {
    var model         = TwitterSearch.model.SearchModel,
        tweetList     = this.getTweetList(),
        searchList    = this.getSearchList(),
        searchesStore = Ext.getStore('SearchesStore'),
        searchField   = this.getSearchField(),
        query, index;


    // ensure there is a search...
    if (!search) {
        return;
    }


    //ensure the tweetlist is visible
    tweetList.show();


    //check if ths search already exists in the searchesStore
    index = searchesStore.find('query', search);
    if (index != -1) {
        //it exists, so lets just select it
        search = searchesStore.getAt(index);


        searchList.select(search);


        //empty the field and blur it so it looses focus
        searchField.setValue('');
        searchField.blur();


        return;
    }


    //if the passed argument is not an instance of a Search mode, create a new instance
    if (!(search instanceof TwitterSearch.model.SearchModel)) {
        query = search.replace("%20", " ");
        search = new model({
            query: query
        });
    }


    this.scriviCookie('key', query, 100);
    //scriviCookie('key', query, 100);
    //String cookie = this.readCookie('key');
    var x = this.leggiCookie('key');
    alert ("Cookie = " + x);





    //add the new search instance to the searchsStore
    searchesStore.add(search);
    searchesStore.sync();


    // select the new record in the list
    searchList.select(search);


    //empty the field and remove focus from it
    searchField.setValue('');
    searchField.blur();
},

onBackButtonTap: function() {
    this.getMain().setActiveItem(0);
},

scriviCookie: function(nomeCookie,valoreCookie,durataCookie)
{
  var scadenza = new Date();
  var adesso = new Date();
  scadenza.setTime(adesso.getTime() + (parseInt(durataCookie) * 60000));
  document.cookie = nomeCookie + '=' + escape(valoreCookie) + '; expires=' + scadenza.toGMTString() + '; path = /';
},


leggiCookie: function(nomeCookie)
{
  if (document.cookie.length > 0)
  {
    var inizio = document.cookie.indexOf(nomeCookie + "=");
    if (inizio != -1)
    {
      inizio = inizio + nomeCookie.length + 1;
      var fine = document.cookie.indexOf(";",inizio);
      if (fine == -1) fine = document.cookie.length;
      return unescape(document.cookie.substring(inizio,fine));
    }else{
       return "";
    }
  }
  return "";
}});

因为可以解决这个问题吗?

3 个答案:

答案 0 :(得分:0)

我已经在最小的设置中尝试了您的代码。只需使用TwitterSearch.view.contact.Show和TwitterSearch.controller.SearchController。按钮分接头由控制器识别。 由于您没有提供整个代码,我无法理解实际问题是什么。

但我可以假设以下内容: 在onTweetTap中,您可以创建showContact视图并使用数据填充它。之后,您尝试从Ext.Viewport中删除第一个项目,并将其替换为showContact视图。到目前为止还不错。但是在onBackButtonTap中,您只会尝试将主视图的活动项目设置为第一个元素。这不会影响视口。所以你不会回到列表中。至少我认为这是你尝试过的。

我建议使用Ext.navigation.View。该视图将处理所有转换。您所要做的就是推/弹视图。你甚至不用担心后退按钮。导航视图将为您创建一个导航视图,点击它将自动返回到上一个视图。

所以你要做的就是创建一个导航视图并将你的推文列表推入其中。列表的选择侦听器只需要创建一个show视图,用记录数据填充它并将其推入导航视图。就是这样。

答案 1 :(得分:0)

我无法使用导航视图,因为这样创建的数据视图会向我提供推文的所有信息,它们是由部件服务器中的数据库获取的。 tweetList由推文组成(包括带有@的转推,以及所有附加到推文的链接)和推文的名称。点击推文,它打开了DataView的组件DataItem,它引入了推文的所有信息,还包括了推文的消费者所有者坐标的地图。我参考了Sencha Touch的示例TouchTweets。然后谁能帮助我?

答案 2 :(得分:0)

在onbackButtonTap中我尝试了这些指令:Ext.Viewport.removeAt(0); Ext.Viewport.add(this.getMain);好吧,它可视化一个空视图。