Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between .create() and .createWithMixins() in ember

What is the difference between .create() and .createWithMixins()? I am not able to find any documentation regarding this. When I create a view instance using .create() and call this._super() in the didInsertElement method then, following error is thrown:

Ember.Object.create no longer supports defining methods that call _super.

But, when I replace .create() with .createWithMixins() everything works fine. Here is the code and the sample js fiddle :

App.SampleView = Ember.View.create({
    sampleProperty : "a",
    didInsertElement : function(){
        this._super();
        this.set("sampleProperty", "b");        
    } 
});

http://jsfiddle.net/bErRT/3/.

like image 911
phkavitha Avatar asked Feb 26 '13 14:02

phkavitha


1 Answers

From Wikipedia:

In object-oriented programming languages, a mixin is a class, which contains a combination of methods from other classes. How such combination is done depends on language, but it is not by inheritance. If a combination contains all methods of combined classes it is equivalent to multiple inheritance.

In Ember instances of objects are created with the create method with no arguments, or with a single hash(kvo) that represent the properties of that type, and they will be automatically populated. Example:

var SomeClass = Ember.Object.extend({
    name: '',
    url: ''
});

// this instance will have a "name" and a "url" properties with blank values
var someInstance = SomeClass.create();

// this instance will have the same properties, but now 
// their values will be populated
var anotherInstance = SomeClass.create({
    name: 'Ember.js',
    url: 'http://emberjs.com'
})

On the other hand, crateWithMixins, allow you to mix another class definition into a single object instance or into another class. So let's say you have the same SomeClass above, but you don't want to sub-class it via extend and create another type. In this case you can use a Mixin to make sure that only that one instance will have that definition of the two classes. Example:

var SomeClass = Ember.Object.extend({
    name: '',
    url: ''
});

// note that you don't extend a mixin, you only create
var SomeOtherClass = Ember.Mixin.create({
    doSomething: function() {
        console.log('doing my thing');
    }
});

// This instance will have a method called "doSomething"
var x = SomeClass.createWithMixins(SomeOtherClass, { 
    name: 'Ember.js', 
    url: 'http://emberjs.com' 
});

// this instance only has methods/properties defined in "SomeClass"
// therefore, no method called "doSomething"
var y = SomeClass.create({ 
    name: 'Google', 
    url: 'http://google.ca'
});

However, if you want to create a new class with a Mixin, you can extend Em.Object, passing the Mixin as the first argument, as follows:

var AnotherClass = Ember.Object.extend(SomeOtherClass, {
    firstName: '',
    lastName: ''
});

var z = AnotherClass.create();
z.set('firstName', 'Hiro');
z.set('lastName', 'Nakamura');
z.doSomething();

Check out the API Documentation as well as this JSFiddle.

Edit: As for _super(), you only use this when you create a new class (via extend). When you create instances of existing classes, you shouldn't call _super().

Another thing. I see you're trying to create a View directly. I believe, based on your code, you should be extending Ember.View and let the framework create instance for your at the appropriate time. If you create manually, you'll be responsible for some parts of its workflow like appending it to the DOM, removing it, etc. Maybe I don't see the whole picture, but based on this code alone, I think you should not call create there and call extend instead, and then you'll be able to call _super()

like image 156
MilkyWayJoe Avatar answered Sep 19 '22 02:09

MilkyWayJoe