Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a reference on a view instance in ember / emberjs from static javascript?

I have seen a lot of questions about that on the web (SOF and Google) but so far no clear answer to the issue.

I have a usual Ember application with various views and controllers. One of my views has an instance method that I would like to call from a static context. Thus in a normal javascript file. I should I get a reference to the view instanciated by ember to call the method on ?

A few lines of code to illustrate my issue :

In ApplicationView.js :

App.ApplicationView = Em.View.extend({
    templateName: 'application',

    myInstanceMethod:function () {
       this.anotherInstanceMethod(some, params);
    },
    // ... more code
});

In MyUtils.js :

var myUtils = myUtils || {
    myMethod: function() {
        myApplicationViewInstance.myInstanceMethod();
    }
};
like image 255
Sephy Avatar asked Feb 13 '13 12:02

Sephy


2 Answers

This is my personal approach to this problem. I am using the "didInsertElement" of Ember.View to register the View in a central place. This works well for singleton views. For non-singleton views, one would have to develop a more sophisticated ViewRegistry.

Ember Part

var App = Ember.Application.create({
    viewRegistry : {
        applicationView : null
    },
});

App.ApplicationView = Ember.View.extend({
    templateName : 'application',
    didInsertElement : function(){
        App.set("viewRegistry.applicationView", this);
    }
});

In MyUtils.js:

var myUtils = myUtils || {
    myMethod: function() {
        App.get("viewRegistry.applicationView").myInstanceMethod();
    }
};
like image 145
mavilein Avatar answered Jan 21 '23 00:01

mavilein


Ember already has a "Global views hash"

search ember.js for Ember.View.views = {}

It is indexed by every views' element id, so getting a view is as easy as:

myView = Ember.View.views[$('.myViewSelector').attr('id')]

My mentor however believes using this method is a dirty hack and advised me to find a better way. He had written a test helper:

window.lookupView = function(key) {
  var activeViews = app.__container__.lookup('router:main')._activeViews;
  if(!activeViews) { throw new Error("No active views."); }
  if(!activeViews[key]) { throw new Error("No view '%@'.".fmt(key)); }
  return activeViews[key][0];
};

which I used to get my desired parentView and then any children with parentView.get('childViews')

like image 34
Robert Carter Mills Avatar answered Jan 21 '23 01:01

Robert Carter Mills