I have imported moment.js into my project and it seems to work just fine in my controllers but for some reason it is not working in my routes.
Controller:
// controllers/users.js
import Ember from 'ember';
export default Ember.Controller.extend({
date: function() {
alert(moment().format('X'));
}.property()
...
});
Route:
// routes/users.js
// (Error: /routes/users.js: line 5, col 29, 'moment' is not defined.
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
var data = { start: moment().startOf('month').startOf('day').format('X') };
return this.store.find('event', data);
}
});
Brocfile:
var app = new EmberApp();
app.import('vendor/moment/moment.js');
I guess this is a JsHint Error. You may want to add the following comment to your Route code.
/* global moment:true */
import Ember from "ember";
....
Also (from ember-cli documentation):
If you want to use external libraries that write to a global namespace (e.g. moment.js), you need to add those to the predef section of your project’s .jshintrc file and set its value to true. If you use the lib in tests, need to add it to your tests/.jshintrc file, too.
Then you don't have to do it to every file your using moment.js in.
Related
I have created an ember app with a component, and I am trying to figure out how I can load a external JS file that is stored in the vendor dir of the app within the component. The code for the component looks like the following,
// app/components/bubbles-page.js
import Ember from 'ember';
export default Ember.Component.extend({
didInsertElement: function() {
// this.$() is a scoped selector to the current view
// bubbles();
// window.onload = bubbles();
// the below line gives the following error,
this.$().bubbles();
// ERROR
//TypeError: this.$(...).bubbles is not a function
// END ERROR
}
});
And the ember-cli-build.js looks like the following,
/* global require, module */
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function(defaults) {
var app = new EmberApp(defaults, {
// Add options here
//
});
// Use `app.import` to add additional libraries to the generated
// output files.
//
// If you need to use different assets in different
// environments, specify an object as the first parameter. That
// object's keys should be the environment name and the values
// should be the asset to use in that environment.
//
// If the library that you are including contains AMD or ES6
// modules that you would like to import into your application
// please specify an object with the list of modules as keys
// along with the exports of each module as its value.
app.import( app.bowerDirectory + '/d3/d3.min.js');
app.import('vendor/bubbles.js');
return app.toTree();
};
Your ember-cli-build.js seems ok.
As for your component file, you can use Ember.run.scheduleOnce('afterRender', callback) to wait for the DOM to render and then call your jQuery plugin.
Also, normally with jQuery plugins, you would have to pass a jQuery selector with which to call the function.
Try the following:
// app/components/bubbles-page.js
import Ember from 'ember';
export default Ember.Component.extend({
didRender() {
this.$('.my-bubbles-container').bubbles();
}
});
Replace .my-bubbles-container with your jQuery selector. I am not familiar with the jQuery plugin you're trying to use but normally that's how jQuery plugins would be used.
You can read more about how to initialize a jQuery component on [this blog post][1].
Updated answer
After learning that your bubbles.js file wasn't a jQuery plugin and that it was a function that operates on the global window, you can call it like this:
// app/components/bubbles-page.js
import Ember from 'ember';
export default Ember.Component.extend({
didRender() {
bubbles();
}
});
If your function is a global function, you will need to add /* global bubbles */ to your component file, or add bubbles to the predef array in the .jshintrc file to avoid the JSHint errors.
This might be a silly question but did you restart your ember serve after adding the import to ember-cli-build? Changes to the Brocfile or ember-cli-build won’t be picked up until you restart.
Another thing you could try is to add { type: 'vendor'} to your import statement: app.import('vendor/bubbles.js', {type: 'vendor'});
I see that Ember.js includes files using 'import name from "module-name"' syntax. For example, in app.js:
import Ember from 'ember';
import Resolver from 'ember/resolver';
import loadInitializers from 'ember/load-initializers';
import config from './config/environment';
I want to include my JS files using this method. But I don't know how to do that. Where should I put my JS files? Or should I do something else?
Here is an example.
My component:
//file app/components/small-logo.js
import Ember from 'ember';
import Logo from 'library/logo';
export default Ember.Component.extend({
mouseEnter: function() {
var logo = new Logo();
logo.changeColor();
}
});
Logo - is a big class, that has many functions. On mouseEnter event I want change the logo's color. Also, I want to start animation when this component shows, but I don't know how to execute a function at this time, it will be another one question.
Here is my component's template:
//file app/templates/components/small-logo.hbs
{{#link-to 'index'}}
<img alt="Logo" src="img/pixel.gif" class="logo">
{{/link-to}}
Here is my js file with class Logo. I don't know how to include it:
//file app/library/logo.js
var Logo = function() {
...
}
Logo.prototype.changeColor = function() {
...
}
In order to be able to import a function/module you must export it in the file, adding an export default Logo; will make it available for import though.
I also recommend using absolute paths to reference it, in your case applicationName/library/logo.
Another more ember-ish way to do what you are trying to accomplish would be to move the logic into the component.
export default Ember.Component.extend({
mouseEnter: function() {
this.changeColor();
},
changeColor: function() {
// your color change logic, you can access the element via this.$()
}
});
And while we're at it, since you are using the ember-cli you can use ES6 syntax:
const { Component } = Ember;
export default Ember.Component.extend({
mouseEnter() {
this.changeColor();
},
changeColor() {
// your color change logic, you can access the element via this.$()
}
});
I create the file app/helpers/test-helper.js:
import Ember from 'ember';
export default Ember.Handlebars.registerBoundHelper('test-helper', function() {
return "Works!";
});
And in the template:
{{test-helper}}
And I get the above error in the console. What am I doing wrong here?
I wrestled with this for awhile myself. The trick is to use makeBoundHelper instead of registerBoundHelper
import Ember from 'ember';
export default Ember.Handlebars.makeBoundHelper('test-helper', function() {
return "Works!";
});
Here's a link to the source code
I'd like to reopen Ember or Ember Data framework classes. Using Ember CLI, where is the right place to put these so that they get initialized property? Here's an example of something I'd like to do:
import DS from 'ember-data';
DS.Model.reopen({
rollback: function() {
this._super();
// do some additional stuff
}
});
I think the best way to execute modules that have side effects would be to create an initializer. Something like this:
// app/initializers/modify-model.js
import DS from 'ember-data';
let alreadyRun = false;
export default {
name: 'modify-model',
initialize() {
if (alreadyRun) {
return;
} else {
alreadyRun = true;
}
DS.Model.reopen({
// ...
});
}
};
Initializers are automatically run by Ember-CLI, so there's no need to call them yourself.
EDIT: As Karim Baaba pointed out, it's possible for initializers to run more than once. For an easy way around that, I've included an alreadyRun flag.
Using an initializers is sufficient but isn't a good practice for writing tests as they're ran multiple times.
Here is an example of how to reopen the text field view to clear the input when focusIn is triggered
app/overrides/textfield.js:
import Ember from 'ember';
export default Ember.TextField.reopen({
focusIn: function(evt) {
this._super(evt);
this.set('value', '');
}
});
app/app.js
import './overrides/textfield';
The pattern is very simple and can easily be used for DS.Model
Export your content as an ES6 module:
import DS from 'ember-data';
export default DS.Model.reopen({
rollback: function() {
this._super();
// do some additional stuff
}
});
Put the file with your reopen content somewhere like app/custom/model.js, then import the file in app/app.js like this:
import SuperModel from './custom/model';
Now all your models have the custom code.
I have some code that needs to run on store.init.
I tried extending the default store in app/store.js, ember-cli seems to pick it up as a store, but the object in this.store is not a store
My store definition:
import DS from 'ember-data';
export default DS.Store.extend({
init:function(){
console.log('watatLoL')
}
});
According to Peter Wagenet, this has changed in Ember Data beta 19. If you're using that version or later, the file is now app/stores/application.js (or app/application/store.js if you're using pods).
Overwriting the store is the same, only the file name/location has changed. If you're using a version of Ember Data lower than beta 19, you can use the old app/store.js file.
I know this is old, but I had to answer this for another question, so I figured I would update this. By default, the Ember-CLI resolver will look for app/store.js, so you can declare your overridden store there.
// app/store.js
import DS from 'ember-data';
export default DS.Store.extend({
init: function() {
console.log('Using custom store!');
return this._super.apply(this, arguments);
}
});
The answer for > Ember 1.13:
The Store now extends the Service so we can just create the app/services/store.js and put the following code to extend/customize the store:
// app/services/store.js
import DS from 'ember-data';
export default DS.Store.extend({
init: function() {
console.log('Using custom store!');
return this._super.apply(this, arguments);
}
});
Here's a sample twiddle