2013-01-07 7 views
5

Gram z ember.js i utknąłem w jakiś sposób na tym, jak zbudować strukturę we właściwy sposób. Mógłbym śledzić all examples, ale mam pewne problemy z ich łączeniem.Ember.js - robiąc to dobrze (struktura, zawiera ogólne pytania)

Używam require.js i kierownicy.

Moja struktura katalogów wygląda następująco:

- app 
- - controllers 
- - css 
- - helpers 
- - lib 
- - models 
- - routes 
- - templates 
- - - partials 
- - views 

Moi application.js wygląda następująco:

require.config({ 
    paths:{ 
     jquery:'lib/jquery-1.7.2', 
     handlebars:'lib/handlebars', 
     ember:'lib/ember', 
     ember_data:'lib/ember-data', 
     text:'lib/requireJS/text', 
     md5:'lib/md5', 
     spin:'lib/spin' 
    }, 

    shim:{ 
     'ember':{ 
      deps:[ 'jquery', 'handlebars'], 
      exports:'Ember' 
     }, 
     'ember_data':{ 
      deps:[ 'ember'], 
      exports:'DS' 
     } 
    }, 

    waitSeconds:15   
}); 

define('application' 
     ,[ 
      // Routes 
      'routes/app_router' 

      // Controller 
      ,'controllers/application_controller' 

      // Views 
      ,'views/application_view' 
      ,'views/category/category_list_view' 

      // Libraries 
      ,'jquery' 
      ,'handlebars' 
      ,'ember' 
      ,'ember_data' 
      ,'spin' 

     ] 
     , function (

      // Router 
      Router 

      // Controller 
      ,ApplicationController 

      // Views 
      ,ApplicationView 
      ,CategoryListView 

      // Models 
      ,Category 
      ,Product 
     ) 
    { 
     return Ember.Application.create({ 

      VERSION: '1.0.0' 

      ,rootElement:'#main' 

      // Load Router 
      ,Router:Router 

      // Load Controllers 
      ,ApplicationController:ApplicationController 

      // Load associated Views 
      ,ApplicationView:ApplicationView 
      ,CategoryListView:CategoryListView 

      // Load Models 
      ,Category:Category 
      ,Product:Product 

      //Persistence Layer,using default RESTAdapter in ember-data.js. 
      ,store:DS.Store.create({ 
       revision:10 
       ,adapter:DS.RESTAdapter.create({ 
        bulkCommit:false 
        ,serializer:DS.Serializer.create({ 
         primaryKey:function (type) { 
          return type.pk; 
         } 
        }) 
        ,mappings:{ 
         //categories:Category 
        } 
        ,namespace:'api' 
        ,url: "https://example.org" 
       }) 
      }) 

      ,ready:function() { 

      } 
     }); 
    } 
); 

Wtedy moim kontroler aplikacji

define(
    'controllers/application_controller' 
    ,['ember' ], 
    function() { 
     return Ember.Controller.extend({ 
      init: function() { 
      } 
     }); 
    } 
); 

widoku aplikacji:

define('views/application_view', [ 
     'text!templates/application.html', 
     'ember' 
    ], 
    function(Application_markup) { 
     return Ember.View.extend({ 
      template: Ember.Handlebars.compile(Application_markup), 
      elementId: 'container', 
      didInsertElement: function() { 
       this.$().hide().show("slow"); 
      } 
     }); 
    } 
); 

I wreszcie, szablon application.html

<div id="container"> 

    <div id="header"> 
     FOO BAR 
    </div> 

    <div id="navigation"> 
     {{outlet mainNavigation}} 
    </div> 

    <div id="content"> 

    </div> 

    <div id="footer"> 

    </div> 

</div> 

Co usiłuję zrobić teraz jest to kolejny szablon do głównego szablonu aplikacji (category_list). Chyba muszę to zrobić w samym szablonie HTML lub w widoku aplikacji - ale w przypadku tego ostatniego nie wiem jak skonfigurować/przeanalizować/powiązać więcej niż jeden szablon.

Jaka jest najlepsza praktyka budowania indywidualnych, niezależnych, modułowych szablonów i łączenia ich? Gdzie dokładnie powinno się to stać? A może to nawet błędne podejście do używania ember.js?

Może jeden z was mógłby wyjaśnić mi pewne rzeczy. Dzięki.

EDIT # 1

app_router.js

define('routes/app_router', 
    ['ember' ], 
    function() { 
     return Em.Router.extend({ 
      enableLogging:true, //useful for development 
      /* location property: 'hash': Uses URL fragment identifiers (like #/blog/1) for routing. 
      'history': Uses the browser's history.pushstate API for routing. Only works in modern browsers with pushstate support. 
      'none': Does not read or set the browser URL, but still allows for routing to happen. Useful for testing.*/ 
      location:'hash', 
      /* location: 'history', 
      rootURL:'/app',*/ 
      root:Ember.Route.extend({ 
       index:Ember.Route.extend({ 
        route:'/' 

        /*,connectOutlets:function (router) { 
         //Render application View ,sign in. 
         v = router.get('applicationController').get('view'); 
         if (v) v.remove(); 
         App.router.get('applicationController').set('loggedin', false); 

         router.get('applicationController').connectOutlet({name:'login', outletName:'loginform'}); 
         router.get('loginController').enterLogin(); 

        }*/ 
       }) 
       /*,contacts:Em.Route.extend({ 
        route:'/contacts', 

        showContact:function (router, event) { 
         router.transitionTo('contacts.contact.index', event.context); 
        }, 

        showNewContact:function (router) { 
         router.transitionTo('contacts.newContact', {}); 
        }, 
        logout:function (router) { 

         jQuery.ajax({ 
          url:'/site/logout', 
          type:'POST', 
          success:function (response) { 
           if (!response.authenticated) { 
            router.get('applicationController').set('loggedin', false).get('view').remove(); 
            router.transitionTo('root.index', {}); 
           } 
          } 
         }) 
        }, 


        index:Em.Route.extend({ 
         route:'/', 
         connectOutlets:function (router) { 
          if (router.get('applicationController').get('loggedin')) 
           router.get('applicationController').connectOutlet('contacts', App.store.findAll(App.Contact)); 
          else router.transitionTo('root.index'); 
         } 
        }), 

        contact:Em.Route.extend({ 
         route:'/contact', 
         index:Em.Route.extend({ 
          route:'/:contact_id', 
          deserialize:function (router, urlParams) { 
           return App.store.find(App.Contact, urlParams.contact_id); 
           debugger; 
          }, 

          showEdit:function (router) { 
           router.transitionTo('contacts.contact.edit'); 
          }, 

          connectOutlets:function (router, context) { 
           if (router.get('applicationController').get('loggedin')) 
            router.get('contactsController').connectOutlet('contact', context); 
           else router.transitionTo('root.index'); 
          } 
         }), 

         edit:Em.Route.extend({ 
          route:'edit', 

          cancelEdit:function (router) { 
           router.transitionTo('contacts.contact.index'); 
          }, 

          connectOutlets:function (router) { 
           if (router.get('applicationController').get('loggedin')) { 
            var contactsController = router.get('contactsController'); 
            contactsController.connectOutlet('editContact', router.get('contactController').get('content')); 
            router.get('editContactController').enterEditing(); 
           } else  router.transitionTo('root.index'); 
          }, 

          exit:function (router) { 
           router.get('editContactController').exitEditing(); 
          } 
         }) 
        }), 
        newContact:Em.Route.extend({ 
         route:'/contacts/new', 

         cancelEdit:function (router) { 
          router.transitionTo('contacts.index'); 
         }, 

         connectOutlets:function (router) { 
          if (router.get('applicationController').get('loggedin')) { 
           router.get('contactsController').connectOutlet('editContact', {}); 
           router.get('editContactController').enterEditing(); 
          } else  router.transitionTo('root.index'); 
         }, 

         exit:function (router) { 
          router.get('editContactController').exitEditing(); 
         } 
        }) 
       })*/ 
      }) 
     }); 
    } 
); 

EDIT # 2

Zmieniłem router teraz jak postępować, ale nie robi nic.

define('routes/apps_router', ['ember'], 
    function() { 
     return Em.Router.extend({ 
      enableLogging:true 
      ,location:'hash' 

     ,map: function (match) { 
      match("/").to("CategoryList", function (match) { 
       match("/").to("mainNavigation"); 
      }); 
     } 

     ,root:Ember.Route.extend({ 
      index:Ember.Route.extend({ 
       route:'/' 

       ,renderTemplates: function() { 
        this.render('mainNavigation', { 
         into: 'CategoryList' 
        }); 
       } 
      // .... 
     }); 
    } 
); 

poważaniem, Christopher

Odpowiedz

4

jeśli używasz najnowszej wersji węgielek z routerem v2, można zrobić coś takiego:

App.Router.map(function (match) { 
    match("/").to("categoryList", function (match) { 
     match("/").to("foo"); 
    }); 
}); 

w szablonie catergoryList, położyć { {outlet}} (opcjonalnie możesz go nazwać)

Następnie twoja trasa dla szablonu, który chcesz wstawić do catergoryList, będzie następująca:

App.fooRouter = Ember.Router.extend({ 
renderTemplates:function() { 
     this.render('foo', { 
      into:'catergoryList' 
     }); 
    } 
}) 

Dobrym przykładem tego w praktyce można znaleźć tutaj: https://github.com/sh4n3d4v15/ember-todos

+0

Shane, dzięki za odpowiedź. Dodałem również mój app_router.js - ponieważ nie mogę jeszcze dostosować twojego podejścia do obecnej struktury mojego routera. Skopiowałem router.js z przykładowej aplikacji. Wygląda na to, że powinienem jeszcze raz przestudiować sekcję routera samouczka, aby poprawnie zrozumieć twoją odpowiedź. –

+0

Bez obaw, jeśli mogę pomóc wyjaśnić dalej, po prostu daj mi znać :) –

+0

Podczas badania możliwości routera z większą głębią znalazłem podejście przy użyciu gniazd w moim routerze. Podobnie jak: connectOutlets: function (router) { router.get ('applicationController') connectOutlet ('mainNavigation', 'CategoryList') } Czy są jakieś wady przy wyborze tego rozwiązania? –