Ember-cli, Masonry, Isotope, Packery. How to use? - ember.js

I need to use them in my ember-cli project.
How to start?
I writed in terminal:
bower install isotope --save
then in my ember-cli-build.js I added app.import ecc..., but then I don't know what to do.
Where to put my intialization script, like this:
$('.grid').isotope({
// options
itemSelector: '.grid-item',
layoutMode: 'fitRows'
});
If I put it in application.hbs it give to me an error and when i change route with {{#link-to}} it doesn't work anymore.
What to do?
In the web there aren't many resources about this.

You should create a component:
ember g component isotope-grid
Then, in component's didInsertElement hook you should call isotope on component's jQuery element:
import Ember from 'ember';
export default Ember.Component.extend({
classNames: ['grid'],
didInsertElement() {
this.$().isotope({
// options
itemSelector: '.grid-item',
layoutMode: 'fitRows'
});
}
})
Then, instead of using <div class="grid"></div>, use:
{{#isotope-grid}}
... HTML goes here
{{/isotope-grid}}

Related

Use an application's route's action in a template component

Firstly, I'm fairly new to Ember, so the way things interact muddles me up easily.
I am working within an existing Ember application. In the app's routes/application.js.es6 there are actions defined. Given that these actions are in the application route, can I access them from anywhere?
I am specifically looking to use one of the application's route's actions in a template/component.
In the component's js file, do I need to inject or import something to use the action from the application route?
This demo perfectly demonstrates the thing you try to achieve.
First, define action in application route:
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
myActionFromApp() {
console.log('myAction from application fired');
}
}
});
Then in template pass name of action to component:
{{my-component myAction='myActionFromApp'}}
Then you can call your ApplicationRoute action from component:
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
myAction() {
this.sendAction('myAction');
}
}
});
In demo I do it when someone clicks button:
<button {{action 'myAction'}}>Fire action myAction</button>
Result in console is:
myAction from application fired
When you click on button which is expected.

how to bind Application controller property in another controller ember

i have search property in ApplicationController and its linked with input field of searching.
i want to access search field of ApplicationController in ProjectController. it should be sync.
i use following code but its not working.
/ app/controllers/projects/index.js (project Controller)
import Ember from 'ember';
export default Ember.Controller.extend({
needs: ['application'],
searchBinding: 'controllers.application.search'
});
/ app/controllers/application.js (Application Controller)
import Ember from 'ember';
export default Ember.Controller.extend({
search: ''
)}
application.hbs
{{input value = search}}
Ember needs is deprecated and is now used differently.
It works like this:
applicationController: Ember.inject.controller('application'),
mySearch: Ember.computed.alias('applicationController.search')
In your hbs template -
{{mySearch}}
 is in sync with applications property "search".
You can access any controller within controller by inject it.
import Ember from 'ember';
export default Ember.Controller.extend({
applicationController: Ember.inject.controller('application'),
searchProperty: Ember.computed.alias('applicationController.search'),
)};
Managing Dependences between Ember controllers
You can access controllers properties included with needs this way :
{{controllers.neededController.property}}
In you case try :
{{input value=controllers.application.search}}
See example here : http://jsfiddle.net/6Evrq/

Dynamically compile a HTMLBars template at runtime in Ember

I want to dynamically compile (and then render) a HTMLBars template at runtime, on the client in Ember. How can I do this?
This answer is now out of date. Please see #poohoka's answer which I've accepted above.
Building off of Kingpin2K's answer to Compile template client side in ember using HTMLbars:
For some background, it might be useful to refer back to Compiling Templates with Ember 1.10. We'll still need to load ember-template-compiler.js. Add
app.import('bower_components/ember/ember-template-compiler.js');
to your ember-cli-build.js.
Then you can write a Component like this:
import Ember from 'ember';
export default Ember.Component.extend({
layout: Ember.computed(function() {
return Ember.HTMLBars.compile(
'{{foo-bar}} <span>' + 'hello' + '</span>'
);
}),
});
This solution will likely break in future relases of Ember, depending on how the Ember Template compilation process changes with the advent of Glimmer 2.
Since Ember 2.10 is now using Glimmer, things might be a bit tricky here. In order to compile a template, you need to include ember-template-compiler.js to your application. I'd recommend using ember-browserify and ember-source.
In your controller, import the compiler as the following.
import Ember from 'ember';
import Compiler from 'npm:ember-source/dist/ember-template-compiler';
export default Ember.Controller.extend({
compileContent() {
const template = Compiler.compile(this.get('dynamicContent'));
Ember.TEMPLATES[`YOUR_TEMPLATE_NAME`] = template;
},
// we observe content changes here
contentDidUpdate: Ember.observer('dynamicContent', function() {
this.compileContent();
}),
});
As tested, your content can contain anything from Ember helpers to your custom components, even your action bindings.
e.g.
<ul>
<li>{{#link-to 'index'}}Home{{/link-to}}</li>
</ul>
<div {{action 'yourCustomAction'}}>
{{your-custom-component params=yourCustomParams model=model flag=true}}
</div>
Now, let's do the magic in your template by using {{partial}} helper.
...
{{partial 'YOUR_TEMPLATE_NAME'}}
...
This method works in Ember 2.13 without deprecation warnings, it should work in future updates. Please note that Ember.TEMPLATES is global variable and the engine seems to cache it somehow, so do not reassign new values to the existing one.
Since Ember 2.13+ (without bower by default) you need to add in your ember-cli-build.js:
app.import('vendor/ember/ember-template-compiler.js');
For Ember version prior to 2.10 you need to include it via bower (also on ember-cli-build.js)
app.import('bower_components/ember/ember-template-compiler.js');
And on the code you need to:
Ember.TEMPLATES['mycompiledcode'] = Ember.HTMLBars.compile('{{foo-bar}} <span>' + 'hello' + '</span>');
In the hbs file call:
{{partial 'mycompiledcode'}}
Or you can make a component like this:
import Ember from 'ember';
export default Ember.Component.extend({
layout: Ember.computed(function() {
return Ember.HTMLBars.compile(
'{{foo-bar}} <span>' + 'hello' + '</span>'
);
}),
});
Based on solution of another answer https://stackoverflow.com/a/37345099/6505594
I'm currently on Ember-2.9.x and I brought in the latest handlebars with my bower.json:
"handlebars": "^4.0.0"
And then added it via my ember-cli-build.js file:
app.import('bower_components/handlebars/handlebars.js');
This has worked for my typeahead component and I don't see any reason why this won't work when upgrading to Ember-2.10 with Glimmer2.

How to programatically add component via controller action in ember 2.x

I am being faced with the same problem on
How to programatically add component via controller action
However since I am using ember cli, I am unable to do so.
Here is my source code
import Ember from "ember";
export default Ember.Component.extend({
actions : {
remove : function(){
this.remove();
},
add : function()
{
Ember.AuthorNameComponent.create().appendTo($('#authors'));
}
},
});
When I try to run this code, I get undefined error. Also name of component is author-name.
Any help, how can I create component via programmatically?
You need to import the component, then you don't need the Ember Global.
import AuthorNameComponent from '../components/author-name-component'
Another way is to have an array of items and base the list of AuthorNameComponent from that.
{{#each items as |item|}}
{{author-name name=item.name}}
{{/each}}

Start foundation js in Ember (using ember-cli)

In my project I am trying to use Foundation's accordion but to no avail. Specifically I have followed this guide here https://coderwall.com/p/azjwaq but it doesn't work. It only works if I explicitly refresh the page, but If I navigate to another controller it stops working. Is this the correct way to initialize foundation 5?
I use foundation 5.3.3 with ember 1.8.0-beta1 and ember-cli 0.44.
Edit:
heads up! I managed to make it work. BUT the whole app now is really really really slow. Specifically I have this inititializer in app/initializer/foundation.js.
import Ember from 'ember';
export default {
name: 'foundation-config',
initialize: function() {
Ember.View.reopen({
startFoundation: function() {
Ember.run.scheduleOnce('afterRender', this, function(){
$(document).foundation();
});
}.on('didInsertElement')
});
}
};
Am I doing something wrong?
Maybe try this:
Stop initializing Foundation for each view. Try extending views which contain accordion to a separate object and then extend it.
App.FoundationView = Ember.View.extend({
didInsertElement: function () {
$(document).foundation();
}
});
App.ViewWhichNeedFoundation = App.FoundationView.extend({
...
})
Simply initializing foundation the normal way manually worked for me. Just before the closing body tag:
<script>
$(document).foundation();
</script>