I am trying to learn Ember using the docs here: http://emberjs.com/guides/templates/handlebars-basics/
I am following the example given on that link and accordingly have the following two files and contents and nothing else. However, when I go the browser and open index.html I do not see Hello World. The World part does not show up. However, according to what is explained near the bottom of that page, World should show up on the page.
Any help in understanding why this is not working would be great. Thanks!
index.html
<h2>First Ember Application</h2>
<script type="text/x-handlebars">
Hello {{name}}.
</script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.rc.1/handlebars.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/ember.js/1.0.0-pre.2/ember-1.0.0-pre.2.min.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js
window.App = Ember.Application.create();
App.ApplicationController = Ember.Controller.extend({
name: "World"
});
you would need an Ember.View to pass variables into and connect with the template. You could set the Context of the controller and have the view use this as its contents, but for your simple example:
window.App = Ember.Application.create();
App.ApplicationController = Ember.Controller.extend({});
App.ApplicationView = Ember.View.extend({
templateName : 'application',
name: 'World'
})
Its worth noting that Ember will look for a set of View, Controller and template with the 'application' naming convention.
Here is a link to the full fiddle http://jsfiddle.net/gNKJj/1/
Related
I am learning SAPUI5. In the link Plunkr. I have a few question.
I am trying to create a JS view and a controller to play with. Why do I have to specify my app, page inside getCore(). what if I would do it outside getCore(). But once I initialize app and Page inside my core method, console is throwing an error. Detail explanation will be really helpful. Thanks :)`
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script
id="sap-ui-bootstrap"
src= "https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-libs="sap.m"
data-sap-ui-compatVersion="edge"
data-sap-ui-preload="async"
></script>
<script src="script.js"></script>
</head>
<body>
<h1>Hello SAPUI5</h1>
<div class="sapUiBody" id="content"></div>
<div id="content1"></div>
</body>
// Code goes here
//debugger
sap.ui.getCore().attachInit(function(){
new sap.m.Text({
text:"Hello World, SAPUI5"
}).placeAt("content");
var app = new sap.m.App({
initialPage : "idViewDashboard1"
});
var page = new sap.ui.core.mvc.View({
id : "idViewDashboard1",
viewName:"ViewChartContainer",
type : sap.ui.core.mvc.ViewType.JS
});
app.addPage(page);
app.placeAt("content1");
});
`
The renderer for class sap.ui.core.mvc.View is not defined or does not define a render function! Rendering of idViewDashboard1 will be skipped! -
getCore() returns the Core instance which has the attachInit() event that
will either be called as soon as the framework has been initialized
or, if it has been initialized already, it will be called immediately.
Because things are loaded asynchronously, attachInit is the best place build your app with the ui5 framework because you can rely on that everything is available and ready.
Your plunkr emits that rather obscure error message because you create an empty instance of the class sap.ui.core.mvc.View that is meant to be abstract and indeed has no renderer method. To instantiate your view you should use the sap.ui.view() method:
var page = sap.ui.view({
id : "idViewDashboard1",
viewName:"viewChartContainer",
type : sap.ui.core.mvc.ViewType.JS
});
See here: https://plnkr.co/edit/ErToSaYgyg7KJ3HX52Oj?p=preview
If you want to learn UI5 i can recommend you to read the Walkthrough. There you can read about many more useful patterns other than that mentioned attachInit() like: encapsulate your app in a component, use XMLViews, use AMD-Modules,...
lately I have been reading through the ember documentation and following as best I can. I have made good progress which I thank God for but lately I have had troubles with routing. Specifically I can get templates to display in the application template but I cannot get children routes to display in the parent resources template. Instead the child template actually replaces it. Here's my code:
index.html
<script type="text/x-handlebars" data-template-name="modals">
<h2>Modals Parent Route</h2>
<p>This is the modals route which is common to all modals</p>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="modals/layout">
<h2>Layout Route</h2>
</script>
<script type="text/x-handlebars" data-template-name="modals/visuals">
<h2>Visuals Route</h2>
</script>
<script type="text/x-handlebars" data-template-name="modals/finish">
<h2>Finish Route</h2>
</script>
<script type="text/x-handlebars" data-template-name="modals/preview">
<h2>Preview Route</h2>
</script>
App.js
App.Router.map(function(){
this.resource('modals', { path:'/modals' }, function(){
this.route('layout');
this.route('visuals');
this.route('finish');
this.route('preview');
});
});
App.LayoutRoute = Em.Route.extend({
renderTemplate: function() {
this.render('modals.layout',{
into: 'modals',
});
}
This is not the full code but I thought it would be all that pertains to this topic. Please feel free to ask me if you need the full file contents.
the renderTemplate method you are using is completely overriding the template for modals that is why, get rid of it. Ember handles the rendering of templates for you, there's no need for it with the basic functionality you are trying to achive.
So I used ember-cli and finally figured out a way to get this working. I used the ember-cli g route to generate my routes. I ran it once for each of my routes except for application. After that things just worked properly. Here is a git repository that someone created for me that will help anyone with this same problem : https://github.com/mooror/mooror. Thanks everyone
If you want nested templates you need nested routes.
this.resource('parent', function() {
this.route('child');
});
See: http://guides.emberjs.com/v1.10.0/routing/defining-your-routes/#toc_nested-resources
My question comes from the need to lazy load different/separate ngApps on one page(bootstrapping them with angular.bootstrap), each of them using its own ngRoute definitions(defined in such a way that they do not overlap each other).
Now I have a working plunkr example and all seems to function well, but somehow I have the feeling that this is not the correct approach so that's why Im asking here for advice.
<!DOCTYPE html>
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<div class="container">
<div class="col-xs-6 well" id="app1">
<h3>App1</h3>
Route 1
Route 2
Route 3
<div class="well" ng-view></div>
</div>
<div class="col-xs-6 well" id="app2">
<h3>App2</h3>
Route 1
Route 2
Route 3
<div class="well" ng-view></div>
</div>
</div>
<script type="text/javascript" src="https://code.angularjs.org/1.2.21/angular.min.js"></script>
<script type="text/javascript" src="https://code.angularjs.org/1.2.21/angular-route.min.js"></script>
<script>
var app1 = angular.module('app1', ['ngRoute']);
app1
.config(function($routeProvider) {
$routeProvider
.when('/:app/:param', {
template: 'app = {{app}}, param = {{param}}',
controller: 'Ctrl1'
})
})
.controller("Ctrl1",['$scope','$routeParams', function($scope,$routeParams) {
$scope.app = $routeParams.app;
$scope.param = $routeParams.param;
}]);
var app2 = angular.module('app2', ['ngRoute']);
app2
.config(function($routeProvider) {
$routeProvider
.when('/:app/:param', {
template: 'app = {{app}}, param = {{param}}',
controller: 'Ctrl2'
})
})
.controller("Ctrl2", ['$scope','$routeParams', function($scope,$routeParams) {
$scope.app = $routeParams.app;
$scope.param = $routeParams.param;
}]);
angular.bootstrap(document.getElementById("app1"), ['app1']);
angular.bootstrap(document.getElementById("app2"), ['app2']);
</script>
</body>
</html>
http://plnkr.co/edit/Y7A9bc3bDUyAXIS13JMZ?p=preview
FYI: I have already checked out ui-router to load separate states on one page, but it all requires for the source code to be loaded upfront(and have a single app.config with all routes in it) which is something I do not want as the Project is quite huge. So for the sake of keeping it simple and modular Im looking for something like the above example.
UPDATE to answer HockeyJ question:
OK I will try to keep this as short as possible. Very basically put - as I said the project could potentially become quite huge, from source code and module dependency perspective. This is why I want to make it in such a way, that each module can be totally separate App, able to be injected at any place and tested separately(thats not really an issue with AnJS). In the same time however the whole project, should be a single page app. As such there should not be screen reloads(to load an App jscript files) etc. Hence comes the lazy loading of scripts on demand and bootstrapping apps to DOM elems. The only possible intersection point of all apps is the URL routing which has strict naming convention for routes i.e. /reports/whatever ; /transactions/whatever etc. and should be managed by ngRoute.
UPDATED:
Checkout overmind project for angular and the demo here
Shows a project broken up into several apps: nav, home, profile, and admin. The nav app is always on the page and is the only app bootstrapped on pageload.
Just take routing out of angular and use something like sammy.js , history.js etc for client side routing.
Use
angular.bootstrap(module, node)
in the routes of your sammy handlers
Also you might want to take a look at react.js (with or without flux) and tide it up with sammy the same way. Consider this example from todombc : https://github.com/tastejs/todomvc/tree/gh-pages/architecture-examples/react
I'm confused, cause I've been trying to find out how to set up a Backbone.js Project.
This is what I've got, I just need to include the scripts and then what? This is where I got lost, I'm pretty sure that simply opening the file I created wouldn't run the project, would it? And also I am following the video tutorial by Thomas Davis but the tutorial doesn't cover how to set up Backbone.js or how to run the project. I notice the difference in our url. What am I missing out? Also If you have some good material for starters like me. tnx!
Here's the code I'm using:
<div id="page">
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<script>
var View = Backbone.View.extend({
el: '.page',
render: function (){
this.$el.html('Hello World');
}
});
var Router = Backbone.Router.extend({
routes: {
'' : 'home'
}
});
var view = new View();
var router = new Router();
router.on('route:home', function ()
{
view.render();
});
Backbone.history.start();
</script>
</body>
</html>
Setting Backbone
You should include the undescore.js, jquery.js and backbone.js in your html and then simply run the file just like normal web app.
If you are familiar with apache, put your app in web root and access like http://localhost/my_app/.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body>
<script src="js/underscore.js"></script>
<script src="js/jquery.js"> </script>
<script src="js/backbone.js"></script>
</body>
</html>
Download underscorejs from here and put in js folder.
Download jquery here.
Download Backbone here.
And then place your backbone function in external JavaScript file and include it after backbone.js.
Fix
And there is something error with your code. You are defined your element using id but trying to access using class notation.
So replace,
var View = Backbone.View.extend({
el: '.page',
render: function (){
this.$el.html('Hello World');
}
});
with,
var View = Backbone.View.extend({
el: '#page',
render: function (){
this.$el.html('Hello World');
}
});
You have to use el: '#page'.
You should include dependencies before including backbone.js.
So replace,
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
With,
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
So I'm checking out Emberjs.
Scroll down a little on the homepage to "GETTING STARTED WITH EMBER.JS IS EASY."
Great, that looks simple, I'll give it a go.
Create a new boilerplate HTML5 file.
Paste their template code into my :
<body></body>
Include emberjs:
<script src="ember.js" type="text/javascript"></script>
Include the JS code they provided into a:
<script type="text/javascript"></script>
Within my head tags. Great, let's see what happens.
Load the page, Console tells me it requires jquery. So no problem I include jQuery. Try again, another error, I need to include handlebars. No problem, I include handlebars. Try again, App is not defined... right... so I include
window.App = Ember.Application.create();
Above the snippet they provided. Try again, DS is not defined. At this point I have no idea where to go next. I took a look at the emberjs guides section as I assume I have to define a DS model somewhere, or something. But the guides were no use.
Am I missing something blatantly obvious, or is this in fact not 'easy' as they put it? What do I have to do to make this basic example work (and why the hell have they given 'basic' code that doesn't work out the box as an example)?
Edit:
My full code thus far:
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js" type="text/javascript"></script>
<script src="handlebars.js" type="text/javascript"></script>
<script src="ember.js" type="text/javascript"></script>
<script type="text/javascript">
window.App = Ember.Application.create();
App.Person = DS.Model.extend({
firstName: DS.attr('string'),
lastName: DS.attr('string'),
fullName: function() {
return this.get('firstName') +
" " + this.get('lastName');
}.property('firstName', 'lastName')
});
App.peopleController = Em.ArrayController.create({
content: App.Person.findAll()
});
</script>
</head>
<body>
<h1>People</h1>
<ul>
{{#each peopleController}}
<li>Hello, <b>{{fullName}}</b>!</li>
{{/each}}
</ul>
</body>
</html>
The problem isn't you, it's that the documentation neglects to list the required dependencies, the naming convention of Handlebars, and suddenly starts talking about a Post controller without providing the code. There's also a couple of places where there's a little bit of cognitive forward referencing going on, so if you know about EmberJs, the guide makes sense, but if you're trying to learning it fresh, you have to hop around, make assumptions, and conduct some tests.
While this isn't the minimal code needed for an EmberJS application, it should be enough to get you started to plug in about 80% of the Getting Started Guide. Hope this helps.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
<script src="jquery-1.9.1.js"></script>
<script src="handlebars.js"></script>
<script src="ember-1.0.0-rc.1.js"></script>
</head>
<body>
<script language="javascript" type="text/javascript">
// Make a global variable -- http://emberjs.com/guides/application/
App = Ember.Application.create({
VERSION: '1.0.0',
// store: Ember.Store.create().from(Ember.fixtures)
});
// http://emberjs.com/api/classes/Ember.Application.html
App.ready = function() {
// alert("App initialized!");
};
// Application Controller, extended with custom properties
App.ApplicationController = Ember.Controller.extend({
appName: 'My First Example',
firstName: "Charlie",
lastName: "Brown",
// initial value
isExpanded: false,
expand: function() {
this.set('isExpanded', true);
},
contract: function() {
this.set('isExpanded', false);
}
});
// A router
App.ApplicationRoute = Ember.Route.extend({
setupController: function(controller) {
// `controller` is the instance of ApplicationController
controller.set('title', "Hello world!");
}
});
</script>
<script type="text/x-handlebars" data-template-name="application">
<header>
<h1>A Header - {{appName}}</h1>
</header>
<div>
Hello, {{firstName}} {{lastName}}.
<p/>
{{#if isExpanded}}
<div class='body'>{{body}}</div>
<button {{action "contract"}}>Contract</button>
{{else}}
<button {{action "expand"}}>Show More...</button>
{{/if}}
<hr/>
{{outlet}}
<hr/>
</div>
<footer>
<H1>A Footer</H1>
</footer>
</script>
</body>
</html>
You do not need to define a DS store unless you have included Ember Data. I have the most basic Ember starting template available on jsfiddle. You can view the source of the rendered frame to get an idea that you only need 3 JS files (which you already have included) in order for the application to work.
From there it is up to you, but yes I admit that the documentation is lacking in regards to starting off from scratch.
From your edit, you have a DS object referenced, but you have not referenced the Ember Data script. It's currently an add-on to the default EmberJS script due to the fact that it is not API locked, whereas the main stream is locked.