Best way to integrate Ember.js with external code

2019-06-07 15:08发布

问题:

I'd like to know what is the best practice when developing an Ember.js app when it needs to react to external code (e.g.,called from and Android app through a WebView, or other pieces of code out of the scope of the Ember Application).

In such scenario having a public interface between the JavaScript world and the Java world is a necessity. That interface may be a an encapsulated object but it needs to be able to make Ember.js router react to change the application state. This kind of use case is not very well defined in Ember.js. For example, AngularJS seems to do a better job at this by providing services (that could be my interface) and Dependency injection. But what mechanisms does Ember.js offers to build an external interface between the App and the external world?

Of course that some hacks could be made (e.g., using App.container) but I'm looking for a way that is consonance with the vision of the frameworks authors. I mean... I don't wish to choose a framework and in the end keep fighting against it. That's why for this specific project I'm considering using a less opinionated framework like Backbone.js. Even though from the (very very small) experience I have with Ember.js I quite like the overall organization of if it.

回答1:

I'd like to know what is the best practice...

I'm not sure there is any one best-practice for connecting with external code.

Android app through a WebView....In such scenario having a public interface between the JavaScript world and the Java world is a necessity. That interface may be a an encapsulated object but it needs to be able to make Ember.js router react to change the application state

Makes sense. Once could use a controller singleton for this purpose. Like any other controller, it would be able to access the router. It might also connect to other controllers to modify their state.

App.ApplicationRoute = Ember.Route.extend({
  setupController: function() {
    bridge = this.controllerFor('bridge');
    // This "works" but uses a global constant
    // Dependency Injection would be better, see below...
    ImaginaryJavaLibrary.sendStateChangesTo(bridge);
  }
})

App.BridgeController = Ember.Controller.extend({
  eventOne: function(data) {
    //react to state change, maybe call router.
  }
})

AngularJS seems to do a better job at this by providing services (that could be my interface) and Dependency injection. But what mechanisms does Ember.js offers to build an external interface between the App and the external world

Services seem cool. FWIW I think maybe AngularJS does a better job at documenting Dependency Injection, but for sure it is a core part of ember as well. Check out this post for an explanation of how to inject objects (like your interface) into an ember application.

http://mcdowall.info/posts/ember-application-initializers/

http://emberjs.com/api/classes/Ember.Application.html#method_register

Also check out this post which describes how to integrate with Pusher - i think this is pretty close to what you'll want to do:

http://livsey.org/blog/2013/02/10/integrating-pusher-with-ember/

FWIW here are Links to a few other approaches we've talked about:

  • Access ember router via global constant (not recommended) Emberjs - how to access router in RC1
  • Use Ember Instrumentation: How to fire an event to Ember from another framework