2013-08-19 31 views
2

我正在創建基於AngularJS,Breeze和RequireJS的單頁應用程序。在使用requirejs與AMD和Breeze合作設置AMD時,我遇到了Breeze對「q」的依賴問題。如果「Q」配置規則是小寫的,即使是在「中間」沒有明確的出口,微風給出了這樣的錯誤:angularjs和requirejs中的「Q」和「q」之間的區別

Uncaught Error: Unable to initialize Q. See https://github.com/kriskowal/q 
"http://localhost:1498/Scripts/shared/breeze.js"breeze.js:1` 

當需要配置的變化,從「Q」到「Q」的所有引用(即使沒有導出),代碼的作品。有誰知道爲什麼會發生這種情況?

這是工作需要配置:

require.config({ 
    baseUrl: '../Scripts', 
    paths: { 
     angular: 'shared/angular', 
     bootstrap: 'shared/ui-bootstrap', 
     dropdowns: 'app/directives/dropdowns', 
     employeeApp: 'app/modules/employeeModule', 
     controllers: 'app/controllers', 
     dates: 'app/directives/dates', 
     jquery: 'shared/jquery', 
     Q: 'shared/q', 
     breeze: 'shared/breeze', 
     config: 'app/services/config', 
     model: 'app/services/model', 
     dataservice: 'app/services/dataservice', 
     expenseInfo: 'app/services/expenseInfo' 
    }, 
    shim: { 
     'angular': { 'exports': 'angular' }, 
     'bootstrap': { deps: ['angular'] }, 
     //'q': { 'exports': 'q' }, 
     'breeze': { deps: ['Q', 'jquery'], 'exports': 'breeze' } 
    }, 
    priority: [ 'angular', 'bootstrap', 'dropdowns', 'jquery', 
       'Q', 'breeze', 'employeeSearch', 'dates' ] 
}); 
+0

錯誤? http://community.phonegap.com/nitobi/topics/works_in_browser_not_on_phonegap_breeze_is_unable_to_initialize_q – zsong

+0

看看這個病房 - http://stackoverflow.com/questions/17819991/angularjs-dataservice-using-breezejs-it-not-resolving-the- promise/17821353#17821353 - 應該有助於讓你知道爲什麼會發生這種情況,以及如何創建一個小型的工作 –

+0

@PWKad,我認爲這個bug比requireJS或BreezeJS更適合Angular。沃德的例子是轉換承諾。我不認爲這涉及$ q或Angular的承諾。不同之處在於需要'q'和'Q' - 如果使用'q',它將不會加載 –

回答

2

技術原因是海風明確查找 「Q」。要找到所有的微風,需要在源代碼中搜索「requireLib」(不是全部單詞)。

微風總是會尋找全球第一,並且由於Q的全球是「Q」這是什麼微風搜索

更多的背景:(是的,我已經經歷了最近一些微風+ RequireJS疼痛)

幸運的是,您可以更改需求路徑。然而用淘汰賽+杜蘭達這不起作用。 Breeze需要'ko',但Durandal需要'淘汰賽'。解決方法是使用RequireJS地圖:

map: { 
    //knockout used by Durandal, ko used by breeze --> anytime ko is requested, substitute knockout 
    '*': { 'ko': 'knockout' } 
} 

微風確實有一些問題,其RequireJS的依賴,因爲它沒有預定義的依賴關係(沒有在其定義呼叫列爲依賴)。這可能是因爲它的一些依賴關係是可配置的(你不想淘汰賽,但我是這樣做的)。這就是爲什麼你需要墊片以確保它們在Breeze要求之前加載。

jQuery有不尋常的AMD行爲。大多數庫在運行時都會查找AMD庫。如果他們找到一個AMD庫(例如RequireJS),他們會自行加載(例如define(...)),並跳過將自己加載爲全局。如果它可以(爲了很好的理由),jQuery確實均爲。這意味着Breeze總能看到並加載全局jQuery,所以不需要從Breeze的'jQuery'創建一個映射到RequireJS的'jquery'。

順便說一句,「即使沒有出口」是無關緊要的。填充程序中的導出屬性用於:加載後,使用全局「微風」作爲模塊值。當微風看到RequireJS時,沒有任何意義,它將自身加載到它而不是全局,並且填充忽略導出。

+0

這爲我解決了它。 – cubski

0

儘管可以通過requireJs加載所有模塊,但自從我的第一個答案以來,我發現了一些困難,這對我來說太麻煩了。

如果你要使用requireJs optomize(RJS)和杏仁,提供與杏仁的切開AMD裝載機組合JS文件,那麼你會發現一些庫錯誤。具體來說,我遇到了Breeze的問題,& Toastr。

optomizer期望顯式定義語句,並明確指定依賴項。 Breeze在加載它們時會使用變量依賴項名稱,因爲它發現它需要它們 - 因爲它的依賴項是在運行時配置的。

另一個問題是使用CDN文件。杏仁不處理任何網絡文件,所以他們必須預先加載。 jQuery是主要的CDN候選者,但它是包括微風在內的許多模塊的必備條件。 optomize shim的不能依賴於任何CDN文件。

我的解決方案

我固定Toastr用我自己的補丁https://github.com/CodeSeven/toastr/issues/135 optomize。

但是因爲修復Breeze會很麻煩,所以我回到了通過捆綁預裝的方式。我還添加了任何我認爲會從CDN中獲益的庫。

予加載微風(及其先決條件)和CDN文件經由ASP.Net捆包 然後定義他們在我main.js

要使用在我的生產代碼這些預定義的預加載到requirejs.config之前requireJs,我配置我的weyland-config.js optomize的空例如

   'jquery':    'empty:', 
       'knockout':    'empty:', 
       'Q':     'empty:', 
       'breeze':    'empty:', 

HTH