上下文更改时刷新会话数据以外的所有数据

时间:2014-07-18 15:05:32

标签: ember.js ember-cli

我正在编写一个小样本应用程序,它将在仪表板和表格中向用户显示一些信息。

使用ember-cli版本0.0.37编写应用程序。和ember.js版本1.5.1。

我正在使用ember-simple-authember-simple-auth-oauth2进行身份验证,使用自定义身份验证器和authroizer将client_id,client_secret和access_token注入到适当的请求中(我完全知道客户端密钥不应该'是在前端应用程序中,但这只是一个内部消费的示例应用程序,而不是我的问题的主题。)

自定义授权程序还会在请求中注入o参数,其值为组织ID。返回数据的API使用access_token和o参数来返回与特定组织有关的数据。组织ID存储在会话中。

所以,一旦我浏览了一个组织,我就有了一个下拉组件,可以让我选择另一个组织。目前,这会调用ApplicationRoute上的操作来更新会话中的值,并清除所有非帐户或组织模型的存储,因为这些模型在应用程序级别使用。

代码:

setSessionOrganisation: function(organisation_id) {
    var self = this;

    /**
     * Check if its the same organisation
     */
    if (this.get('session.organisation_id') == organisation_id) {
        return;
    }

    /**
     * Get the organisation for the id provided
     */
    this.store.find('organisation', organisation_id).then(
        function(org) {

            /**
             * Update the session details
             */
            self.set('session.organisation_id', org.get('id'));
            self.set('session.organisation_name', org.get('name'));

            /**
             * Get all types
             */
            var store = self.container.lookup('store:main');
            var types = [];
            var typeMaps = store.typeMaps;
            $.each(typeMaps, function(key) {
                if (typeMaps.hasOwnProperty(key)) {
                    var type = typeMaps[key].type.typeKey;
                    if (type != 'account' && type != 'organisation'){
                        types.push(typeMaps[key].type.typeKey);
                    }
                }
            });

            /**
             * Clear data for types
             */
            for (var i = 0; i < types.length; i++) {
                store.unloadAll(types[i]);
            };
        });
}

我觉得上面的代码有点hackish,但我还没有找到另一种方法来返回商店中当前的模型类型。

当调用此操作并刷新数据时,我想刷新/重新加载当前路由。一些路线将是动态的,并使用对象ID作为动态段。这些路由需要重定向到其列表路由。其他路线在导航时会进行延迟加载数据。

所以我的问题是:

  • 清除商店数据有比上面更好的方法吗?
  • 如何触发路线重装?
  • 如果在包含动态细分的路线中,如何重定向到父路线?

作为奖励问题,卸载目前尚未显示的观看/路线的所有数据是否存在危险?

谢谢!

1 个答案:

答案 0 :(得分:0)

我在@marcoow

的帮助下,达成了符合我标准的决议

根据对该问题的评论,我们讨论了重新加载整个应用程序以刷新数据存储缓存。虽然这种方法确实有效,但浏览器完全重新加载页面时会出现闪烁,我宁愿只重新加载数据并让应用程序自行排序。如果调用App.reset(),也会出现此闪烁。

我探索了其他选项并找到了Ember.Route.refresh()方法。这似乎导致嵌套路由在从应用程序路由调用时重新加载其模型。

在我的应用程序中,我已经在初始化程序中扩展了存储,因此我可以调用一个函数来卸载商店中的所有记录,对于商店中的每种类型的模型,还提供要排除的模型名称列表:

app/initializers/custom-store.js

import DS from 'ember-data';

var CustomStore = DS.Store.extend({
    /**
     * Extend the functionality in the store to unload all instances of each type
     * of data except those passed
     *
     * @param  {Array} exclusions List of model type names to exclude from data
     *                            unload
     */
    unloadAllExcept: function(exclusions) {

        var typeMaps = this.get('typeMaps');

        for (var type in typeMaps) {
            if (typeMaps.hasOwnProperty(type)) {

                var typeKey = (typeMaps[type].type && typeMaps[type].type.typeKey) ? typeMaps[type].type.typeKey : false;

                if (typeKey && exclusions.indexOf(typeKey) === -1) {
                    this.unloadAll(typeKey);
                }
            }
        }
    }
});


export
default {
    after: 'store',
    name: 'custom-store',

    initialize: function(container /*, app*/ ) {
        container.unregister('store:main');
        container.register('store:main', CustomStore);
    }
};

这是从app/routes/application.js setSessionOrganisation中的Action调用的:

setSessionOrganisation: function(organisation_id) {
    var _this = this;

    /**
     * Check if its the same organisation
     */
    if (this.get('session.organisation_id') === organisation_id) {
        return;
    }

    /**
     * Get the organisation for the id provided
     */
    this.store.find('organisation', organisation_id)
        .then(
            function(org) {

                /**
                 * Update the session details
                 */
                _this.get('session')
                    .set('organisation_id', org.get('id'));
                _this.get('session')
                    .set('organisation_name', org.get('name'));

                /**
                 * Clean the local data cache of all data pertaining to
                 * the old organisation
                 */
                _this.store.unloadAllExcept(['account', 'organisation']);

                /**
                 * refresh the application route (and subsequently all
                 * child routes)
                 */
                _this.refresh();
            });
    }

作为一个脚注,这个解决方案不能满足我提出的第三个问题,但我已经意识到这个问题与处理API响应有关,而且必须在模型钩子中处理。