简体   繁体   中英

Ember: Access ember data 'store' object from utility class

I have a utility class for validating usernames in my ember application and have it setup as specified in the ember-cli docs. I do client-side username validation in several places in my application (components and controllers) so I wanted to pull the validation logic out into a reusable method.

The file is at /app/utils/username-validator.js and I can successfully include the file in my app by importing it like so: import usernameValidator from 'my-app/utils/username-validator';

This works great so far and I've used the pattern for several utility classes. The problem I'm running into now is that I'd like the username-validator method to include a check to see if the username already exists.

As I am using Ember-Data I'd like to check the Ember-Data store . By default, the store appears to only be accessible in controllers and routes. How can I make it accessible in my utility class? All the injection examples I've seen deal with injecting the store into other first class Ember objects like components.

Is it possible to inject the store into a simple utility class as well?

Thank you!

I am using the following versions:

Ember-cli v0.2.6
ember.debug.js:4888 DEBUG: -------------------------------
ember.debug.js:4888 DEBUG: Ember             : 1.12.0
ember.debug.js:4888 DEBUG: Ember Data        : 1.0.0-beta.18
ember.debug.js:4888 DEBUG: jQuery            : 1.11.3
ember.debug.js:4888 DEBUG: Ember Simple Auth : 0.8.0-beta.2
ember.debug.js:4888 DEBUG: -------------------------------

===== Updated with detailed solution based on answer from torazaburo ======

Creating a service works great. Here is how I did it using ember-cli (v0.2.6) and ember v1.12.0

  1. Create your service inside of /app/services/<service-name>.js

The service blueprint will look like this (note the name of the service is based on the name of the file):

import Ember from "ember";

export default Ember.Service.extend({
   myFunction: function(){

   }
});
  1. Create an initializer for your service in /app/initializers/<service-name>.js which is used to inject your service into the different top level Ember objects (such as routes, controllers, components etc). Note that the file name of the initializer should match the file name of your service.

The blueprint for the initializer will look like this:

export function initialize (container, app) {
       // Your code here
}

export default {
  name: '<service-name>',
  initialize: initialize
};

To give a concrete example, lets say your service is called validator and contains a bunch of validation routines. You want to inject the validator into all controllers, and you also want to inject the Ember Data store into the validator itself. You can do it like this:

export function initialize (container, app) {
  // Inject the Ember Data Store into our validator service
  app.inject('service:validator', 'store', 'store:main');

  // Inject the validator into all controllers and routes
  app.inject('controller', 'validator', 'service:validator');
  app.inject('route', 'validator', 'service:validator');
}

export default {
  name: 'validator',
  initialize: initialize
};

Make your utility into a "service", into which you can inject the store. Actually, it sounds like your utility should be a service anyway, even if it doesn't need the store. By making it a service, for instance, it becomes much easier to stub it out when writing tests. With a service, you need neither import anything nor do any global injections in initializers, you can simply say

export default Ember.Component.extend({

    myService: Ember.inject.service(), // inject services/my-service.js

    foo: function() {
         this.get('myService').api1(...);
    }

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM