Ember.js - robi to dobrze (struktura, zawiera, ogólne pytania)
Bawię się z ember.js i utknąłem jakoś odkrywając, jak zbudować strukturę we właściwy sposób. Mogę pójść za tymwszystkie przykłady, ale mam pewne problemy z ich połączeniem.
Używam require.js i kierownicy.
Moja struktura katalogów wygląda tak:
- app
- - controllers
- - css
- - helpers
- - lib
- - models
- - routes
- - templates
- - - partials
- - views
Mój application.js wygląda tak:
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 () {
}
});
}
);
Następnie mój kontroler aplikacji
define(
'controllers/application_controller'
,['ember' ],
function () {
return Ember.Controller.extend({
init: function() {
}
});
}
);
Widok 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>
Teraz próbuję dołączyć inny szablon do głównego szablonu aplikacji (lista_kategorii). Myślę, że albo muszę to zrobić w samym szablonie HTML, albo w widoku aplikacji - ale w przypadku tego drugiego 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 w całość? Gdzie dokładnie to powinno się stać? Czy jest to nawet niewłaściwe podejście do korzystania z ember.js?
Może ktoś z was może sprawić, że niektóre rzeczy będą dla mnie bardziej jasne. Dzięki.
EDYCJA # 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();
}
})
})*/
})
});
}
);
EDYCJA # 2
Zmieniłem router w następujący sposób, ale nic nie robi.
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'
});
}
// ....
});
}
);
Pozdrawiam, Christopher