2013-02-05 55 views
2

我正在使用Ext JS 4.1創建一個CRM類型的應用程序。要連接到服務器端,我通過RemotingProvider使用Ext Direct。如何避免由於Ext Direct和動態語言環境加載而導致的嵌套異步回調?

在應用程序啓動並呈現之前,我想通過Ext Direct從服務器檢索一些全局變量,主要是當前登錄用戶的配置語言及其配置的權限。然後,根據用戶的語言(從該結果),我需要加載Ext JS語言環境文件和我自己的自定義語言環境文件。 (請注意,這些必須被裝載在創建任何組件之前,因爲它們不會被事後應用。)

因此,該程序是:

  1. 通過Ext.php.Globals.getGlobals
  2. 得到全局得到內線區域通過Ext.loader.loadScript
  3. 獲得通過應用程序的語言環境Ext.loader.loadScript
  4. 設置視

自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

回答

3

你的概念有點奇怪,所以我有一些建議給你。我在很多項目中直接使用,大多數他們需要本地化和相當複雜的交流管理。

  • 你的應用程序在開始之前不應該有需要解析或加載的東西。
  • 語言&應在主應用程序視圖加載時提供本地化
  • 您的前端永遠不應解析任何訪問控制。你可以(在大多數情況下)完美地做到這一點的直接API
    • 減少API這些行動在用戶訪問(當應用程序主視圖做好準備,這也恰好)

這使您的應用程序更快,並且您的生活更輕鬆。

更新

的時間用戶登錄或只是要求MAINVIEW你應該像支持的瀏覽器語言或大量信息至少當用戶選擇的語言。憑藉這些知識,您只需準備視圖即可。

前端中的acl不安全,需要在服務器端重新檢查,因此應該避免或簡化。直接最簡單的方法是提供一個匹配用戶訪問的API並在前端檢查這一點。這是一種隱式訪問控制。如何實現這個要看的用戶界面,但有很多方法

更新2

你爲什麼不每種語言提供一個構建?我沒有看到任何反對它的理由。或者從您的應用程序中拆分框架,這些類允許您更新,而客戶端仍然可以使用緩存的框架庫。

可以輕鬆地檢查控制器(後端)訪問和方法(後端)訪問API。控制器可能是您的選項卡和您的菜單元素的行爲。因爲API是全局可用的,您只需檢查對象或屬性是否存在。讓我們假設我們有一個名爲Car後端控制器和方法稱爲Drive我們可以檢查這個喜歡

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

感謝您的回答。對於您的建議,我有一些後續問題:2)如何在主視圖加載時「提供」語言和本地化?在詢問服務器後,我只知道正確的語言,而且我沒有看到同步加載區域設置文件的方法。 3)你可以擴展這個嗎?你會將我的'MyApp.util.hasPermission'移動到服務器上,以便每行都調用服務器嗎?我的應用程序有一個標籤界面,權限將決定加載哪些標籤。 – pulsar

+0

@脈衝我編輯了我的文章 – sra

+0

我猜你正在建議一種類似於Izhaki提出的方法。在那裏看到我的評論爲什麼這不起作用。 - 當然,在服務器端檢查訪問控制,但是如果不能使用,我想隱藏某些UI元素。關於「API匹配用戶訪問」部分:你是否建議我使用類似於:'Ext.php.User.hasPermission('usermgmt',function(data){if(data == true)app.getController(' usermgmt');})'? – pulsar

1

除非我失去了一些東西很明顯,我拿上這將是完全不同的。

我有一個類似的情況下,系統中的用戶可能是superuseradmin,並基於此,主菜單將更改。

但我不會從Ext應用程序代碼中向服務器查詢此信息。相反,我的頭包括非常相似,如何直接加載的東西:

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

然後globals.php有東西沿着這些路線:

<?php 
if ($iUserIsSuperuser) { 
?> 

gUserIsSuperuser = true; 

<?php 
} 
?> 

然後作爲區域js文件 - 不能只需簡單的正確的在您的index.php使用條件?

+0

在加載時設置「超級用戶」標誌非常不安全 - 任何訪問瀏覽器控制檯的人都可以在一秒鐘內更改該變量。除非我錯了,並且你在每個後端點擊檢查用戶權限? –

+0

亞歷山大對安全性的擔憂是讓我無法選擇這種方法的一個方面,另一個是這樣的:當使用Sencha Cmd編譯用於生產的JavaScript文件時,我最終得到的只是一個'all-classes.js',if我理解正確。但用戶信息和語言環境不能靜態編譯,所以我必須仍然加載它們。在'all-classes.js'之前,我不能這樣做,因爲Ext.define將會是未定義的,並且之後已經太晚而無法應用於視口生成。 – pulsar

+0

@AlexanderTokarev - 通過其他方式確保安全。只需說這方面的內容。 – Izhaki