如何避免由于Ext Direct和动态语言环境加载导致的嵌套异步回调?

时间:2013-02-05 18:20:29

标签: javascript extjs asynchronous extjs4 ext-direct

我正在使用Ext JS 4.1来创建CRM类型的应用程序。要连接到服务器端,我通过RemotingProvider使用Ext Direct。

在应用程序启动和渲染之前,我想通过Ext Direct从服务器检索一些全局变量,主要是当前登录用户的已配置语言及其配置的权限。然后,根据用户的语言(从该结果),我需要加载Ext JS语言环境文件和我自己的自定义语言环境文件。 (请注意,必须在创建任何组件之前加载它们,因为之后不会应用它们。)

所以,程序是:

  1. 通过Ext.php.Globals.getGlobals
  2. 获取Globals
  3. 通过Ext.loader.loadScript
  4. 获取Ext语言环境
  5. 通过Ext.loader.loadScript
  6. 获取应用语言环境
  7. 设置视口
  8. 从1.-3开始。是异步的,除了嵌套回调之外别无他法:

    Ext.application({
      name: 'MyApp',
    
      launch: function() {
        var app = this;
    
        // Welcome to callback hell...
        Ext.php.Globals.getGlobals(function(data) {
          // insert globals into app namespace
          Ext.apply(MyApp, data);
    
          // load ext locale
          Ext.Loader.loadScript({
            url: 'ext/locale/ext-lang-'+MyApp.currentUser.culture.toLowerCase()+'.js',
            onLoad: function() {
              // load app locale
              Ext.namespace('MyApp.locale');
              Ext.Loader.loadScript({
                url: 'app/locale/'+MyApp.currentUser.culture.toUpperCase()+'.js',
                onLoad: function() {
    
                  // FINALLY, set up viewport
                  var viewport = Ext.create('MyApp.view.Viewport', {
                    controller: app
                  });
    
                  if (MyApp.util.hasPermission('usermgmt'))
                    app.getController('Locations');
    
                  // and so on ...
    
                }
              });
            }
          });
        });
      }
    }); // end application
    

    还有其他更优雅的方式来编写这段代码吗?我知道有异步流的库,但是这些可以使用Ext JS API吗?或者我可以以某种方式强制Ext.syncRequire为我加载语言环境(所以我只有一层嵌套用于getGlobals调用)?我自己的语言环境定义了一个类,但Ext语言环境没有。另外,这会不会弄乱用 Sencha Cmd 编译源文件?

2 个答案:

答案 0 :(得分:3)

你的概念有点奇怪,因此我有一些建议。我在许多项目中直接使用,大多数都需要本地化和相当复杂的AC管理。

  • 您的应用程序在开始之前不需要解决或加载某些内容。
  • 语言&应在主应用程序视图加载时提供本地化
  • 您的前端永远不应解决任何访问控制。您可以(对于大多数情况)使用直接API完美实现此目的
    • 将API缩减为用户有权访问的这些操作(当应用程序主视图准备好时也会发生这种情况)

让您的应用更快,生活更轻松。

<强>更新

用户登录或只是请求主视图时,您应该拥有大量信息,例如支持的浏览器语言,或者至少在用户选择语言时。有了这些知识,您只需要准备视图。

前端内的acl不安全,需要在服务器端重新检查,因此应该避免或简单。直接的最简单方法是提供与用户访问匹配的API,并在前端进行检查。这是一种隐式访问控制。如何实现这取决于UI,但有很多方法

更新2

为什么不为每种语言提供一个版本?我认为没有任何理由反对它。或者从您的应用程序中拆分框架&amp;允许您更新的类,而客户端仍然可以使用缓存的框架库。

可以轻松检查API的控制器(后端)访问和方法(后端)访问。控制器可能是您的选项卡和操作您的菜单元素。因为API是全局可用的,您只需要检查对象或属性是否存在。让我们假装我们有一个名为Car的后端控制器和名为Drive的方法我们可以检查这个

if (Car) {
    // has controller access
    if (Car.Dirve) {
        // has access to the 'drive' action
    }
}

答案 1 :(得分:1)

除非我遗漏了一些非常明显的东西,否则我对此的看法将完全不同。

我在用户可能是superuseradmin的系统中也有类似的情况,基于此,主菜单会发生变化。

但我不会在Ext应​​用程序代码中向服务器查询此信息。相反,我的标题包含与直接加载非常相似的内容:

<script type="text/javascript" src="globals.php"></script>

然后globals.php有以下几点:

<?php
if ( $iUserIsSuperuser ) {
?>

gUserIsSuperuser = true;

<?php
}
?>

那么对于locale js文件 - 你不能简单地使用条件在index.php中包含正确的文件吗?