So in Ember it's awesome that you don't necessarily need to extend a view for a template and instead one can automagically be created for your template.
My question is, for the base HTML element of a templates automagically created view how can I specify a class name so I can namespace the CSS?
// template /////////////////
<script type="text/x-handlebars" data-template-name="contacts">
...
</script>
// html /////////////////
<div id="ember337" class="ember-view MyCoolClassName"> <---- custom class name in here
...
</div>
I know I can do it by extending a view for this template but to simply add an additional class name that seems overkill. Thoughts?
I think that isn't possible, because the root tag of a view, like this:
<div id="ember337" class="ember-view MyCoolClassName">
is generated from, your properties:
SomeView = Ember.View.create({
elementId: 'ember337',
classNames: ['ember-view', 'MyCoolClassName'],
tagName: 'div'
});
If you don't want to create a view to add a simple class, you can do:
<script type="text/x-handlebars" data-template-name="contacts">
<div class="MyCoolClassName">
Hello world
</div>
</script>
And in your css:
.ember-view .MyCoolClassName {
/*some style */
}
Related
Sorry if this is a really obvious questions but I have the following routes:
Web.Router.map(function () {
this.resource('orders', function(){
this.resource("order", {path:":order_id"});
});
});
And for my orders template I have something like:
<div class="someclass">
{{outlet}}
</div>
And what I want todo is:
{{#if onOrderRoute}}
<div class="someclass">
{{outlet}}
{{else}}
<div class="someotherclass">
{{/if}}
</div>
I was wondering what the best way of doing this is, or am I mising something?
There are multiple ways to accomplish this. The view has a layoutName property you can use to specify your layout. Another option is to specify a property on your child view, and then your template can bind to that by using the view property.
For example:
Web.OrderView = Ember.View.extend({
childView: true
);
Then, in your template you bind to view.childView
{{#if view.childView}}
<!-- code goes here -->
{{/if}}
Further, you can even create a mixin and then just inject that mixin into every view.
Web.ChildViewMixin = Ember.Mixin.create({
childView: true
});
Web.ChildView = Ember.View.extend(ChildViewMixin, {
});
In Marionette with Underscore templates, is it possible to 'include' one template file into another template file - so that common markup can be shared across multiple templates?
We use requireJS to load the .tpl files as and when - and then assign a tpl file to a Marionette view;
View.MyView = Marionette.ItemView.extend({
template: 'parent_template.tpl'
});
Where 'parent_template.tpl' contains something like.
<h1>A Parent View</h1>
<button class='btn-one'>One</button>
<button class='btn-two'>Two</button>
<button class='btn-three'>three</button>
What I would like to do is extract say the buttons to a common tpl, that other tpl's could use, something like...
Where 'parent_template.tpl' contains something like.
<h1>A Parent View</h1>
{{child_template.tpl}}
And 'child_template.tpl' contains something like.
<button class='btn-one'>One</button>
<button class='btn-two'>Two</button>
<button class='btn-three'>three</button>
And then lots of other templates could pull in the shared template.
Any ideas?
The way that I solved this was with templateHelpers.
Load the partial templates as per usual with require JS.
Then pass a reference to the child template into the parent template via the templateHelper;
define(['tpl!parent.tpl', 'tpl!child.tpl'], function (ParentTemplate, ChildTemplate) {
View.MyView = Marionette.View.extend({
template: ParentTemplate,
templateHelpers: function() {
return {
childTpl: ChildTemplate
}
}
});
}
The parent template includes the child via the helper
<h1>parent template</h1>
<%= childTpl(obj) %>
The child can access the data if you pass 'obj' - the template model
<h2>this is the child, that can access the parent data <%= title %></h2>
For me it smells odd including template in template.
You can instead use Mariontte.LayoutView with subview:
buttons subview :
Buttons = Marionette.ItemView.extend({
template: 'child_template.tpl'
});
layout :
MyView = Marionette.LayoutView.extend({
template: 'parent_template.tpl',
region : {
buttonRegion : '.myButtonsRegion'
},
onShow : function(){
var buttons = new Buttons();
this.buttonRegion.show(buttons);
}
});
and then parent_template.tpl :
<h1>A Parent View</h1>
<div class="myButtonsRegion"></div>
I have the following template:
...
<i class="icon-fixed-width {{myIcon}} icon-4x"></i>
...
And my controller has myIcon defined as a simple string:
App.NodesController = Ember.ArrayController.extend({
...
myIcon : 'icon-cloud',
...
});
(this setting is in controller. The background is that I want to reuse the template for different controllers, so that just by 'configuring' each controller I get a different icon)
The problem is that {{myIcon}} produces a surprising result (to me, at least!):
<i class="icon-fixed-width <script id='metamorph-8-start' type='text/x-placeholder'></script>icon-cloud<script id='metamorph-8-end' type='text/x-placeholder'></script> icon-4x"></i>
How can I achieve the expected result:
<i class="icon-fixed-width icon-cloud icon-4x"></i>
by accessing myIcon in the controller?
Use {{bindAttr class='myIcon'}} ...Reference to bindAttribute Classes
I would like to do the following handlebar script:
The color:{{object.labelColor}} seems not working (Cf. other post).
One solution seems to bind the complete style attribute on the "javascript side" but I would like to avoid managing the "fixed" part of the style (text-align:left) on that side.
Is there a solution to make something similar to my sample code (dynamic part on the js side,fixed part on the html view) ?
<div class="label" style="color:{{object.labelColor}};text-align:left">{{object.name}}</div>
You could use 'classNameBindings', and define a set of css rules to the corresponding classes.
Js
Ember.View.create({
classNameBindings: ['isUrgent'] // array of class names
isUrgent: true //conditional to set class name
});
css
.is-urgent{
background-color: #356aa0;
}
Resource
http://emberjs.com/api/classes/Ember.ContainerView.html#property_classNameBindings
If you have to use styles instead of classes, and want to change only a portion of the style strings at the time, one alternative would be using $.css, applying the style changes you want. For example:
<script type="text/x-handlebars">
<h1>App</h1>
{{view App.SomeView}}
</script>
<script type="text/x-handlebars" data-template-name="some-view">
<div style="color:#00F;text-align:left">
Some View<br />
<button {{action changeColor on="click"}}>Change Color</button>
</div>
</script>
<script type="text/javascript">
App = Em.Application.create();
App.SomeView = Em.View.extend({
templateName: 'some-view',
changeColor: function(e) {
console.log('changing color');
this.$('div').css('color', '#F00');
}
});
</script>
In the script above I'm using jQuery's css function to change the color attribute whatever elements my selector returns from within SomeView instance (in this case as I only have one div, I'm using the element as a selector). There are other (and likely better) ways to do this, but I hope this helps.
The problem with this solution as it is, is that you can't keep the state of the style attribute as it's not bound to any property, that's why I think binding classes would be better in the long run.
Is there a way to pass in a custom class or id namespace instead of the default ember?
example: turn this
<body class="ember-application">
<div class="ember-view"></div>
</body>
into:
<body class="myapp-application">
<div class="myapp-view"></div>
</body>
You can pass in a custom id, instead of the default "ember-[numview]".
Just set the elementId field of the Ember.View Class
var mainView = Ember.View.create({
tagName: "section",
elementId: "main"
})
will generate:
<section id="main" class="ember-view">
</section>
To remove/modify the default className "ember-view", you need find and edit the classNames field on the PrototypeMixin on the View class...
Em.View.PrototypeMixin.mixins[2].properties.classNames = []
var mainView = Ember.View.create({
tagName: "section",
elementId: "main"
})
will generate:
<section id="main">
</section>
No idea about the side effects...
No.
"ember-application" is hardcoded in Ember.EventDispatcher#setup, and "ember-view" is similarly a static string in the classNames property on Ember.View. Because 'classNames' is a concatenated property (which means subclasses combine their values, instead of replace them), you can add 'myapp-view' to the classNames array, but you can't remove (easily) values from super classes.