1. #1
    Sencha User
    Join Date
    Mar 2012
    Posts
    24
    Vote Rating
    1
    rvelasquez is on a distinguished road

      1  

    Default Problem with Sencha Profiles

    Problem with Sencha Profiles


    Hi,

    I'm trying to wrap my head around Sencha profiles and I'm finding it a little awkward to use. I would like to have a different layout between Android and iPhone (different position of tab bar). Here are the two profile specific views:

    Code:
    Ext.define("myapp.view.iphone.MyView", {
        extend: 'Ext.TabPanel',
        xtype: 'myview',
    
    
    	config: {
    		tabBarPosition: 'bottom',
                    .........
    });
    Code:
    Ext.define("myapp.view.android.MyView", {
        extend: 'Ext.TabPanel',
        xtype: 'myview',
    
    
    	config: {
    		tabBarPosition: 'top',
                    .........
    });
    Then in my profiles I'm loading the profile specific view:

    Code:
    Ext.define('myapp.profile.Android', {
        extend: 'Ext.app.Profile',
    
    
        config: {
            name: 'Android',
            views: [
    'myapp.view.android.MyView'
            ]
        },
        ..........
    });
    
    Code:
    Ext.define('myapp.profile.iPhone', {
        extend: 'Ext.app.Profile',
    
    
        config: {
            name: 'iPhone',
            views: [
    'myapp.view.iphone.MyView'
            ]
        },
        ..........
    });
    

    Finally in my main application view:

    Code:
    Ext.define("myapp.view.Main", {
        extend: 'Ext.Container',
        xtype: 'mainview',
        config: {
    		layout: 'card',
    		items: [
    			{ xtype: 'someotherview' },
    			{ xtype: 'myview' }
    		]
        }
    });
    What I was hoping to happen is that Sencha would only load the views of the first profile that returns true when isActive is called. Then there would be only one view with the xtype "myview". That way when the Main view loads it will load the myview that's specific to the device I'm launching. However it looks like I can't use xtype that way. It looks like it loads all the views (both Android specific and iPhone). So when it tries to resolve the xtype "myview" it doesn't get the right one. It seems really awkward if I have to create a profile specific version of the Main view just so I can get this work. How should I go about getting this to work?

  2. #2
    Sencha - Community Support Team edspencer's Avatar
    Join Date
    Jan 2009
    Location
    Palo Alto, California
    Posts
    1,939
    Vote Rating
    9
    edspencer is a jewel in the rough edspencer is a jewel in the rough edspencer is a jewel in the rough

      0  

    Default


    The framework does indeed load all of the specified views, even if the profile isActive function did not match. The reason for this is that if we don't do it then we don't have a universal app - you'd have to build an Android version of the app and an iPhone version of the app, then figure out which to serve to which devices, presumably somewhere on the server. Instead, we create a universal version of the app that can bootstrap itself on the device and figure out what to do.

    The main downside of this approach is exactly what you've just pointed out - you can't overload the xtypes in this manner. It's something I'd like us to come up with a better solution around in the next minor release or two, and would welcome ideas and feedback.
    Ext JS Senior Software Architect
    Personal Blog: http://edspencer.net
    Twitter: http://twitter.com/edspencer
    Github: http://github.com/edspencer

  3. #3
    Sencha User
    Join Date
    Mar 2012
    Posts
    24
    Vote Rating
    1
    rvelasquez is on a distinguished road

      0  

    Default


    So is the recommended approach to create different versions of all controllers/views etc for each profile? That could be really messy if you are dealing with more than two profiles. I'm pretty new to Sencha and I'm only using the JSON config style to configure my views/controllers. It seems like there must be a way to do this dynamically like a factory that creates different views based on the profile that is currently active. What's the proper way to construct objects dynamically instead of through the JSON style construction.

  4. #4
    Sencha - Community Support Team edspencer's Avatar
    Join Date
    Jan 2009
    Location
    Palo Alto, California
    Posts
    1,939
    Vote Rating
    9
    edspencer is a jewel in the rough edspencer is a jewel in the rough edspencer is a jewel in the rough

      0  

    Default


    At the moment I'd just say to avoid using the same xtype when you have profile-specific views. That may mean you end up with xtypes like 'overviewios' and 'overviewandroid'. You could factory this if you want to keep your code cleaner - should be simple enough but that's not built into the framework at the moment.
    Ext JS Senior Software Architect
    Personal Blog: http://edspencer.net
    Twitter: http://twitter.com/edspencer
    Github: http://github.com/edspencer

  5. #5
    Sencha User
    Join Date
    Mar 2012
    Posts
    24
    Vote Rating
    1
    rvelasquez is on a distinguished road

      0  

    Default


    Yeah ... that's what I was trying to avoid because I have controllers that ref the view so if I create a profile specific view I also need to create a profile specific controllers for each controller that references that view. I realize I can use inheritance to reduce code duplication but overall it's just awkward. Using Sencha has been awesome but the experience of using profiles has been inconsistent with how the amazing the rest of Sencha is.

  6. #6
    Sencha - Community Support Team edspencer's Avatar
    Join Date
    Jan 2009
    Location
    Palo Alto, California
    Posts
    1,939
    Vote Rating
    9
    edspencer is a jewel in the rough edspencer is a jewel in the rough edspencer is a jewel in the rough

      0  

    Default


    Yup, definitely something we want to improve
    Ext JS Senior Software Architect
    Personal Blog: http://edspencer.net
    Twitter: http://twitter.com/edspencer
    Github: http://github.com/edspencer

  7. #7
    Ext JS Premium Member anselmtmcclain's Avatar
    Join Date
    Mar 2008
    Location
    Northern California
    Posts
    85
    Vote Rating
    3
    anselmtmcclain is on a distinguished road

      0  

    Default


    I'm glad I found this thread as I had the exact same misconception as the original poster.

    I thought that the xtypes existed to provide exactly this kind of abstraction. It seems like the profile mechanism could work with the ClassManager to wire an xtype to the appropriate implementation class when multiple profile-specific implementations exist.

    Since for my app profile-specific controllers would be overkill, I'll just switch manually between view classes within controller methods as needed. Not a big deal, but I'm not getting much then from the entire convention of the profile. It seems like you need to branch your view construction at the top "launch" level if you want to use profiles as presented in the docs.

    If there are any updated discussions or ideas on this one, I would really appreciate a link to the thread,etc. Thanks.


    Edit: One approach might be to set/overwrite aliases within the profile's launch method, via Ext.ClassManager.setAlias(). Using that, I can re-write aliases to profile-specific subclasses myself within the profile, then use the aliases in my controllers/views without any switching and still get the implementation class I want. Curious if anyone has tried such a thing or sees any downsides.

  8. #8
    Sencha Premium Member
    Join Date
    Dec 2011
    Posts
    13
    Vote Rating
    1
    DodgyDave is on a distinguished road

      1  

    Default


    We encountered a similar problem and add the xtype in the launch method of the profile.

    So the code would be something like

    Code:
    Ext.define("myapp.view.iphone.MyView",
    ...
    Ext.define("myapp.view.android.MyView"
    ,...
    
    Ext.define('myapp.profile.android', {
        extend: 'Ext.app.Profile',
        launch: function() {
            myappp.view.android.MyView.addXtype('myView');
        }
    ...
    
    Ext.define('myapp.profile.iphone', {
        extend: 'Ext.app.Profile',
        launch: function() {
            myappp.view.iphone.MyView.addXtype('myView');
        }
    
    ...

  9. #9
    Sencha User
    Join Date
    Mar 2012
    Posts
    28
    Vote Rating
    0
    gcw07 is on a distinguished road

      0  

    Default


    I experienced the same problem recently and my solution was to setup different xtypes for each profile views. Then setup controllers where they extend a base controller. Within the profile controllers, put the references to point to the correct view xtype. So you might have something like.

    controller/phone/Search.js
    Code:
    Ext.define('App.controller.phone.Search', {
        extend: 'App.controller.Search',
        config: {
            refs: {
                mainPanel     : 'mainPanelPhone',
                searchPanel    : 'searchPanelPhone',
            }
        }
    });
    controller/tablet/Search.js
    Code:
    Ext.define('App.controller.tablet.Search', {
        extend: 'App.controller.Search',
        config: {
            refs: {
                mainPanel     : 'mainPanelTablet',
                searchPanel    : 'searchPanelTablet',
            }
        }
    });
    controller/Search.js
    Code:
    Ext.define('App.controller.Search', {
        extend: 'Ext.app.Controller',
    });
    Since Sencha only executes the controller from the active profile, the references are correct within "controller/Search.js". No idea if this is the correct way to do it or not, but it does seem to work and keeps majority of the code within the base controllers since the logic isn't different for different views.

  10. #10
    Ext JS Premium Member anselmtmcclain's Avatar
    Join Date
    Mar 2008
    Location
    Northern California
    Posts
    85
    Vote Rating
    3
    anselmtmcclain is on a distinguished road

      0  

    Default


    Thanks for both replies - both of those are very useful suggestions.

    I hadn't thought of just overriding the refs in profile-specific controller subclasses, and leaving all the logic (using the refs) in the base controller class.

    Dodgy Dave, I think that your approach is the same / similar to what I noted in my edit above. I'm going to stick with ClassManager.setAlias() as addXtype() is documented as private, but I think the end result is exactly the same, and gets us the re-wired xtypes we want.