Patterns for initializing components


#1

Anyone have thoughts on best practices for initializing state and variables within a component?

Seems like didInsertElement is a convenient place for this kind of logic. But was wondering if there are any other patterns worth considering.

To be more concrete imagine a very simple component with some flags

App.MyComponent = Ember.Component.extend({
    someFlag: null,
    anotherFlag: null,
    actions: {
        updateSomeFlag: function(value) {
            this.set('someFlag', value);
        },
        updateAnotherFlag: function(value) {
            this.set('anotherFlag', value);
        }
    },

    didInsertElement: function() {
        // Initialize some state for this component
        this.set('anotherFlag',"foo");
        this.set('someFlag', "bar");            
    }

});

I suppose implicitly these parameters can be defined by the component in the template that declares it

{{ my-component someFlag="foo" anotherFlag="bar" }}

But wondering about the case where I want a much simpler interface surface area with more complex internal logic around setting up the default values of my component, that the external world shouldn’t have to think about.

{{ my-component }}

didInsertElement seems perfectly adequate, but wondering if other people are finding that they use a dedicated initialization method, or ever find they need to call super.


#2

In your example, I’d just default the values:

App.MyComponent = Ember.Component.extend({
    someFlag: "foo",
    anotherFlag: "bar"
})

Assuming it’s more complex than that, handling it on init should do the trick:

App.MyComponent = Ember.Component.extend({
    setupFlags: function(){
        this.setProperties({  // more logic here
          someFlag: "foo",
          anotherFlag: "bar"
        });
    }.on("init")
})

That’s basically the same as overriding init but without the need to remember to call this._super()

hth


Passing model data to a component through its template
#3

Hello, I’m new to Ember, just a month ago I started to develop thick web client based on Metronic layout. I have a question regarding use of init event. I don’t see it here in the docs http://emberjs.com/api/classes/Ember.Component.html , just the private ‘init’ method. Could you please explain what is ‘init’? I heard on podcast that one should not rely on private API because it can be deprecated in future versions.

Best regards


#4

@Marek_Ziel the init method is a special function that gets called whenever some object in Ember is created.

In its most basic form init looks like this inside Ember.CoreObject

  init() {},
  __defineNonEnumerable(property) {
    o_defineProperty(this, property.name, property.descriptor);
    //this[property.name] = property.descriptor.value;
  },

See source code here:

Most of the time you don’t need to implement your own init methods unless you are doing something very special.

I think there are two basic patterns, in most cases I would prefer the “setup” method that gets called when init is called.

Your own setup method that happens when init event is fired.

setup: Ember.on('init', function() {
  // do setup work ...
  
  // function happens whenever init is called
  // but you don't have to call super because
  // you are not overriding init
  // think of this function happening "along side" init
  
  // because of this no need to call super
}),

When we need to override init

init: function() {
  // do initialization work...
  
  // this function is called whenever the object is created
  // you are overriding an 'init' method that already exists
  // in the class hierarchy
  
  // You can think of this function happening "in place of" init
  // therefore you need to call super to make sure other init methods
  // further up in the hierarchy get called
  
  
  // call super to initialize other init methods 
  this._super();
},

Hopefully this clarifies…


#5

Can anyone provide a clue as to whether didInsertElement or init is better? I have just used didInsertElement for the first time and it feels OK.

In my case I needed to check a model that was passed into the component in order to set the value of a simple flag. Specifically, if the model has no label attribute set then I set the editable flag to true. This allows users to create unlabelled objects via drag/drop and add a label when they see it rendered. For previously labelled objects, they are not editable by default (but the editable flag can be toggled with a click).