Component communication - ember.js

ember-cli 0.2.7
ember 1.13-beta2
Im trying to setup a component to handle overlays in my webapp. I want to be able to open this overlay from across the application but I'm having trouble figuring out how to do so. Here is what I got.
It seems like ember doesn't recognise the service though. Any help greatly appreciated!
The service
import Ember from 'ember';
export default Ember.Service.extend(Ember.Evented, {
publish: function() {
return this.trigger.apply(this, arguments);
},
subscribe: function() {
this.on.apply(this, arguments);
},
unsubscribe: function() {
this.off.apply(this, arguments);
}
});
The navigation component
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'nav',
classNames: ['l-navigation'],
events: Ember.inject.service('event-bus'),
actions: {
openDashboard: function() {
this.get('events').publish('dashboard:open');
}
}
});
And then the 'overlay' component
import Ember from 'ember';
export default Ember.Component.extend({
tagName: 'section',
classNames: ['l-dashboard'],
events: Ember.inject.service('event-bus'),
init: function() {
this.get('events').subscribe('dashboard:open', this, 'openDashboard');
},
openDashboard: function() {
alert('opening dashboard');
}
});
EDIT - By popular demand :-)
Here is the jsbin for the issue. http://emberjs.jsbin.com/cesotamuza/1/

Related

How to use Bootstrap-3-Typeahead work with embe-data?

My ember version:
DEBUG: -------------------------------
Ember : 2.11.0
Ember Data : 2.11.1
jQuery : 3.1.1
Ember Simple Auth : 1.2.0
DEBUG: -------------------------------
Before I use ember data, I have a component like this:
import Ember from 'ember';
export default Ember.TextField.extend({
didInsertElement: function() {
var _this = this;
this.$().typeahead({
source: function(query, process) {
$.getJSON("/api/" + _this.get('modelName'), {query: query, access_type: 'typeahead'}, function(data) {
process(data);
});
}
})
},
willDestroyElement: function() {
this.$().typeahead('destroy');
}
})
Use this component:
{{typeahead-input type="text" modelName='shipping_spaces' value=shippingSpace class="form-control"}}
And this component work with Bootstrap-3-Typeahead(https://github.com/bassjobsen/Bootstrap-3-Typeahead).
But when I use ember-data to my project, I did not know how to use Bootstrap-3-Typeahead work with ember-data. Because all data came from this.store.query('order'), not use ajax any more.
So if I must use typeahead, I must design a addo? Thanks.
Just change the content of the search function. The search function has a second argument process as the callback function. Call it when you receive the result from store.
Here is an example:
import Ember from 'ember';
export default Ember.TextField.extend({
store: Ember.inject.service(),
didInsertElement: function() {
var _this = this;
this.$().typeahead({
source: function(query, process) {
this.store.query('order', query).then(function(data){
process(data);
});
}
})
},
willDestroyElement: function() {
this.$().typeahead('destroy');
}
})
Alternative 2:
Now you may think that injecting store to a component is bad. It depends! If this is an order-querying component, it is ok. But if you really don't want to inject store to a component, just use a closure action.
Example for closure action:
didInsertElement: function() {
var _this = this;
this.$().typeahead({
source: function(query, process) {
let remoteFunc = this.get('remoteCallFunc');
remoteFunc(query).then(function(data){
process(data);
});
}
})
},
And usage is:
{{typeahead-input type="text" remoteCallFunc=(action 'retrieveShippingSpaces')
value=shippingSpace class="form-control"}}

ember-simple-auth overriding sessionAuthenticated

Folks,
I've been trying to get ESA to redirect to specific pages after login and logout events without success.
I'm trying to do this by overriding the "sessionAuthenticated" method, but have also tried setting the "routeAfterConfiguration" setting with no luck.
At the moment, login sends me to "/", and logout sends the app to "/undefined".
I'm using simple-auth-token as a JWT authenticator strategy.
The code for my application route looks like this...
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
export default Ember.Route.extend(ApplicationRouteMixin,{
actions: {
sessionAuthenticated: function() {
console.log('sessionAuthenticated: authentications ok');
window.location.replace('/profile');
},
},
});
My login.js is as follows:
import Ember from 'ember';
const {service} = Ember.inject;
export default Ember.Route.extend({
session: service('session'),
errorMessage: null,
model: function(){
return Ember.Object.create({
identification:'',
password: '',
errorMessage: this.get('errorMessage')
});
},
setupController: function(controller, model) {
controller.set('credentials',model);
},
actions: {
authenticate: function(credentials) {
console.log(credentials);
this.get('session').authenticate('simple-auth-authenticator:jwt', credentials)
.catch((reason) => {
console.log('Login Error');
credentials.set('errorMessage', reason);
});
},
},
});
Does anyone have any idea what I might be doing wrong here?
Cheers,
Andy
OK. Found the problem. These are not actions - they're methods. So I just had to promote the methods out of the actions object and it's all come good.
So the correct routes/application.js looks like this:
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
export default Ember.Route.extend(ApplicationRouteMixin,{
sessionAuthenticated: function() {
console.log('sessionAuthenticated: authentications ok');
window.location.replace('/profile');
},
});

Access model from another route in EmberJS

I have this router.js:
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('analyses', function() {
this.route('new', { path: 'new'});
this.route('show', { path: ':analysis_id' });
this.route('edit', { path: ':analysis_id/edit'});
this.route('dataFunctions', { path: ':analysis_id/dataFunctions', resetNamespace: true }, function() {
this.route('new', { path: 'new'});
});
});
export default Router;
and these 2 models
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
dataFunctions: DS.hasMany('dataFunction', {async: true}),
});
and
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
analysis: DS.belongsTo('analysis', {async: true})
});
The contents of routes/data-functions/index.js:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
console.log(this.store.findRecord("analysis", id).get("dataFunctions"));
}
});
The contents of routes/analyses/index.js:
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.store.findAll("analysis");
},
setupController(controller, model) {
controller.set("analyses", model);
}
});
The contents of routes/analyses/show.js:
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.store.findRecord('analysis', params.analysis_id);
},
setupController(controller, model) {
controller.set("analysis", model);
}
});
When I navigate to /analyses/1/dataFunctions my analysis model is loaded (it is show in ember inspector) but I can’t seem to access it in my data-functions/index.js route. How do I go about this? I need the analysis model to extend findAll in my data-function adapter to change the url for a rails-api nested resource.
I tried using this.store.modelFor("analysis").get("id") but it errors saying get is not a funcion.
I am using Ember 2.0.1 and Ember Data 2.0.0. I am lost here, any help would be greatly appreciated.
It's returning no mode found because you're returning a log statement in the dataFunctions route. Give this a try.
export default Ember.Route.extend({
model(params) {
return this.store.findRecord("analysis", params.analysis_id)
.then( (analysis) => {
return analysis.get('dataFuncitons');
})
}
});
Ok, so went through the code there was a few issues. There was a typo in analysis, and the resetNamespace is making things act weird. Also removed some of the redundant path names.
Router.map(function() {
this.route('analysis', function() {
this.route('new');
this.route('show', { path: ':analysis_id' });
this.route('edit', { path: ':analysis_id/edit'});
this.route('dataFunctions', { path: ':analysis_id/dataFunctions'}, function() {
this.route('new');
});
});
});
Rename the dataFunctions model to data-function to reflect proper conventions, e.g. using singular and dasherizing.
The analysis model
export default DS.Model.extend({
name: DS.attr('string'),
dataFunctions: DS.hasMany('data-function', {async: true}),
});
The data-function model
export default DS.Model.extend({
name: DS.attr('string'),
analysis: DS.belongsTo('analysis', {async: true})
});

how to inject store in service ember.js

I tried to inject the store from the initializer without success, so I use lookup on init in my service, but I don't like it too much, I would rather keep things separated and put the injection in the initializer...
Ember : 1.11.1
Ember Data : 1.0.0-beta.16.1
jQuery : 1.11.2
NOT WORKING:Initializer
//app/initializers/initializer-store.js
export default {
name: 'initializer-store',
after: 'store',
initialize: function(container, application) {
application.inject('service:mtg-level-service', 'store', 'store:main');
}
};
WORKING:Service
//app/services/mtg-level-service.js
import Ember from 'ember';
export default Ember.Service.extend({
availableIn: ['controllers', 'routes'],
store: null,
init: function() {
this._super();
this.set('store', this.container.lookup("store:main"));
}
});
As of Ember v1.10:
import Ember from 'ember';
export default Ember.Service.extend({
store: Ember.inject.service('store')
});

this.get('content') (inside controller) is undefined after migrating to ember-cli

After migrating from global-namespace-version to ember-cli (0.1.4), my code doesn't work as before. I'm watching the content property in my controller to handle the data, fetched in my route. But nothing happens, the groupedResults function isn't called.
The data is fetched successfully (Ember Inspector shows all projects), so the content property shouldn't be empty.
Router
import Ember from 'ember';
import AuthenticatedRouteMixin from 'simple-auth/mixins/authenticated-route-mixin';
export default Ember.Route.extend(AuthenticatedRouteMixin, {
controllerName: 'organization-projects',
model: function() {
return this.store.find('project');
},
renderTemplate: function() {
// render all projects
this.render('organization/projects-list', {
into: 'application'
});
// render toolbar
this.render('organization/toolbar', {
into: 'application',
outlet: 'toolbar'
});
}
});
Controller
import Ember from 'ember';
export default Ember.Controller.extend({
groupedResults: function () {
console.log(this.get('content'));
}.property('content.[]')
});
Are there some breaking changes that I've missed?
Got it: changed controllerName: 'organization-projects' to controllerName: 'organization.projects'.
But I wonder why this worked in my old global-namespace-version.