2014-01-14 32 views
1

模塊化灰燼應用工作intermittently-代碼這個帖子有很多細節,所以請多多包涵與requirejs

我的大部分Ember.js開發經驗是預發佈版(0.9.8.1)和我相當新的路線。我已經投入了大量的時間瞭解他們,創造了一個工作程序:

http://mbregistry.info/

問題是,我的代碼間歇性不工作(在Chrome中大多顯着)。起初,我遇到了無法找到模板的問題。我重寫了路線圖,並指定像這樣的模板:

腳本/ users.js

define(['scripts/app','text!scripts/templates/UserIndex.html'], 
function (app, templateUserIndex) { 
    //route is called app.UserIndexRoute 
    app.UserIndexView = Ember.View.extend({ 
     template: Ember.Handlebars.compile(templateUserIndex), 
     Created: function() { 
      return app.ParseDate(this.get('controller.model.created')).toLocaleDateString(); 
     }.property('controller.model.created'), 
     MailTo: function() { 
      return 'mailto:' + this.get('controller.model.email'); 
     }.property('controller.model.email') 
    }); 
}); 

我驗證requirejs加載使用文本插件HTML ...但後來發現, StackOverflow上的其他人在路由對象中使用「模板」和視圖時遇到問題。因此,我沒有與之對抗,而是移除了「模板」行,並更新了我的App類,以明確設置ready()事件中所有視圖的模板(因爲我知道路由將默認模板名稱)

scripts/app.js

define(['jquery', 
    'handlebars', 
    'ember', 
    'text!scripts/templates/Application.html', 
    'text!scripts/templates/Loading.html', 
    'text!scripts/templates/Index.html', 
    'text!scripts/templates/OwnedCarsIndex.html', 
    'text!scripts/templates/OwnedCar.html', 
    'text!scripts/templates/UserIndex.html'], 
function (jQuery, handlebars, ember, templateApplication, templateLoading, templateIndex, templateOwnedCarsIndex, templateOwnedCar, templateUserIndex) { 
    App = Ember.Application.create({ 
     ready: function() { 
      Ember.TEMPLATES['application'] = Ember.Handlebars.compile(templateApplication); 
      Ember.TEMPLATES['loading'] = Ember.Handlebars.compile(templateLoading); 
      Ember.TEMPLATES['index'] = Ember.Handlebars.compile(templateIndex); 
      Ember.TEMPLATES['ownedCars/index'] = Ember.Handlebars.compile(templateOwnedCarsIndex); 
      Ember.TEMPLATES['ownedCar'] = Ember.Handlebars.compile(templateOwnedCar); 
      Ember.TEMPLATES['user/index'] = Ember.Handlebars.compile(templateUserIndex); 
     }, 
     LOG_TRANSITIONS: true, 
     LOG_TRANSITIONS_INTERNAL: true, 
     LOG_VIEW_LOOKUPS: true, 
     LOG_ACTIVE_GENERATION: true 
    }); 

    App.Router.map(function() { 
     this.resource('users', function() { 
      this.resource('user', { path: ':user_id' }, function() { 
       this.resource('ownedCars', { path: 'cars' }, function() { 
        this.resource('ownedCar', { path: ':ownership_id' }, function() { 
         this.resource('expenses'); 
        }); 
       }); 
      }); 
     }); 

     this.resource('cars', function() { 
      this.resource('car', { path: ':car_id' }); 
     }); 
    }); 

    return App; 
}); 

這樣就解決了模板間歇無法加載的問題。但是現在又間歇性地,我遇到了這條路線的一個問題。我有一個鏈接來幫手,這裏是一些控制檯輸出爲網頁時遇到這個問題:

DEBUG: ------------------------------- 
DEBUG: Ember  : 1.3.0 
DEBUG: Handlebars : 1.1.2 
DEBUG: jQuery  : 1.10.2 
DEBUG: ------------------------------- 
Attempting URL transition to/
generated -> route:application Object {fullName: "route:application"} 
generated -> route:index Object {fullName: "route:index"} 
Transition #1: Beginning validation for transition to index 
Transition #1: application: calling beforeModel hook 
Transition #1: application: resolving model 
Transition #1: application: calling afterModel hook 
Transition #1: application: validation succeeded, proceeding 
Transition #1: index: calling beforeModel hook 
Transition #1: index: resolving model 
Transition #1: index: calling afterModel hook 
Transition #1: index: validation succeeded, proceeding 
Transition #1: Validation succeeded, finalizing transition; 
generated -> controller:application Object {fullName: "controller:application"} 
Rendering application with default view <(subclass of Ember.View):ember209> Object {fullName: "view:application"} 
generated -> controller:index Object {fullName: "controller:index"} 
Rendering index with default view <Ember._MetamorphView:ember225> Object {fullName: "view:index"} 
Transitioned into 'index' 
Transition #1: TRANSITION COMPLETE. 
generated -> route:cars Object {fullName: "route:cars"} 
generated -> route:cars.index Object {fullName: "route:cars.index"} 
generated -> route:users Object {fullName: "route:users"} 
generated -> route:user Object {fullName: "route:user"} 
generated -> route:user.index Object {fullName: "route:user.index"} 

,但是當我嘗試點擊「修改個人資料」鏈接,將其用在鏈路中產生要幫手,我得到這個:

Attempting transition to user.index 
Transition #2: Beginning validation for transition to user.index 
Transition #2: application: using context from already-active handler 
Transition #2: application: validation succeeded, proceeding 
Transition #2: users: calling beforeModel hook 
Transition #2: users: resolving model 
Transition #2: users: calling afterModel hook 
Transition #2: users: validation succeeded, proceeding 
Transition #2: user: calling beforeModel hook 
Transition #2: user: resolving model 
Assertion failed: You used the dynamic segment user_id in your route user, but App.User did not exist and you did not override your route's `model` hook. 
Transition #2: user.index: transition was aborted 

我不知道爲什麼它試圖訪問App.User,而不是App.UserRoute(App.UserRoute具有重載模式功能,正確生成的模型)

任何幫助非常感謝:)

更新:我有(我甚至沒有提及) 一個問題我solved-我需要使用requirejs的配置勻場Ember.js:

require.config({ 
    paths: { 
     'text': 'scripts/references/text', 
     'jquery': 'scripts/references/jquery-1.10.2.min', 
     'handlebars': 'scripts/references/handlebars-1.1.2', 
     'ember': 'scripts/references/ember-1.3.0' 
    }, 
    shim: { 
     'ember': { 
      deps: ['handlebars', 'jquery'], 
      exports: 'Ember' 
     } 
    } 
}); 

這擺脫了間歇性「模塊未找到jquery「或」找不到模塊句柄「(這隻發生在轉儲緩存時發生)。所描述的主要問題仍然存在。從調試器控制檯,這裏是我注意到,當它呈現在網頁,唯一的區別...

工作頁

Transition #1: TRANSITION COMPLETE. 
generated -> route:cars Object {fullName: "route:cars"} 
generated -> route:users Object {fullName: "route:users"} 

不工作頁面(錯誤當你點擊鏈接)

Transition #1: TRANSITION COMPLETE. 
generated -> route:cars Object {fullName: "route:cars"} 
generated -> route:cars.index Object {fullName: "route:cars.index"} 
generated -> route:users Object {fullName: "route:users"} 
generated -> route:user Object {fullName: "route:user"} 
generated -> route:user.index Object {fullName: "route:user.index"} 

如果您發現非工作頁面輸出,Ember正在爲尚未使用的路由生成路由對象...爲什麼有時候這隻會發生?

回答

1

找到了!當我意識到模板沒有正確編譯時,應該對我更加明顯,並嘗試了我的問題中所示的解決方法。

我的問題的根本原因是,在瀏覽器加載註冊路由的JavaScript之前,Ember在處理鏈接到幫助器時生成路由(間歇性競爭條件)。我通過讓模塊返回一個函數然後像構造函數一樣使用它來解決這個問題。

腳本/所以最終代碼app.js看起來是這樣的:

define(['jquery', 
     'handlebars', 
     'ember', 
     'scripts/users'], 
function (jQuery, handlebars, ember, usersModule) { 
    App = Ember.Application.create({ 
    }); 

    usersModule = new usersModule; 

    App.Router.map(function() { 
     this.resource('users', function() { 
      this.resource('user', { path: ':user_id' }, function() { 
       //.. 
      } 
     } 
    } 

    return App; 
}); 

現在我腳本/ users.js模塊如下所示:

define(['text!scripts/templates/UserIndex.html'], 
function (gravitar, templateUserIndex) { 
    return function() { 
     App.UserIndexRoute = Ember.Route.extend({ 
      model: function (param) { 
       return this.modelFor('user'); 
      } 
     }); 
     App.UserIndexView = Ember.View.extend({ 
      template: Ember.Handlebars.compile(templateUserIndex), 
      Created: function() { 
       return App.ParseDate(this.get('controller.model.created')).toLocaleDateString(); 
      }.property('controller.model.created'), 
      MailTo: function() { 
       return 'mailto:' + this.get('controller.model.email'); 
      }.property('controller.model.email') 
     }); 
    } 
}); 

所以在結論,require.js仍然是爲了它的目的(我真的很喜歡它),但是,將它與Ember.js整合可能比我使用的黑客更好。我的問題是,我是一個白癡,並沒有指望Ember.js在加載所有模塊之前處理任何東西(其中一些模塊註冊路由)。 我看到的間歇行爲是Ember在應用程序視圖中處理鏈接到幫助器之前,所有路線都已註冊。

ember-app-kit看起來很有趣,但它看起來像通過提供圍繞使用Ember.js(我還沒準備好)的整個框架來解決問題。但絕對感謝亞當的幫助:)

+0

想要提出這個問題後的幾個月 - 我找到並切換到Ember CLI。我強烈建議使用它,而不是像上面那樣做任何事情。 –

1

我不確定爲什麼你在用戶模型而不是UserRoute的時候得到了預期的結果,但我可以告訴你,Ember不能很好地與AMD模塊一起使用。它與resolver有關,它負責在請求時找出容器中事物的正確名稱。 ember-app-kit project正在解析器的new version與es6模塊transpiler(它將es6模塊轉換到AMD模塊)一起工作。您可能會想到如何重寫默認解析器以使其與require.js一起工作。

+0

您發佈到解析器的鏈接太棒了!這絕對是我需要看的下一個:)將更新此任何發現 –

+0

看着這幫助我瞭解更多信息。發生的事情是鏈接助手渲染,大部分時間,它只加載頂層路線(我沒有定義;因此它們會生成)。間歇時間,它由於某種原因加載嵌套的路由,這是奇怪的,除了它產生它們(而不是使用我指定的那些)。點擊發生時,解析器沒有找到.model()方法(因爲它使用了生成的路由)並且默認爲Ember Data的find(),它也沒有找到該模型(因爲我沒有有一個名爲App.User的模型) –