0

I searching the best way to objects in AngularJS. The goal is to use it like this model = new Model 'wowwowwow'

So I started with this approach:

app.factory 'Model', ->
  (blah) ->
    Model =
      blah: ''
      foo: []
    Model.blah = blah
    Model

Then I wanted to move constructor actions in separate function that would not be accessible from class instance:

app.factory 'Model', ->
  constructor = (blah) ->
    @blah = blah
    @

  (blah) ->
    constructor.call
      blah: ''
      foo: []

Finally I wanted to use goals of coffeescript and tried to solve my task in kinda obvious way:

app.factory 'Model', ->
  class Model
    blah: ''
    foo: []
    constructor: (blah) ->
      @blah = blah
  (blah) ->
    new Model blah

But in this last case doesn't work as needed:

var1 = new Model 'test'
var1.foo.push 'blah'
var2 = new Model 'asdasd'
console.log var2.foo

the problem here is that var2 after creation will have same values as var1 (they are linked in fact).

Here is the plunk for this problem.

So the questions are:

  1. What is wrong with my 3rd approach?

  2. How can I change 3rd approach to make it work with coffeescript's OOP features.

  3. Are any better approaches for my task?

2
  • I suggest you do a Google search on "Object Oriented JavaScript" or "Creating Classes in JavaScript" or "Prototype Inheritance" or similar things. You'll find hundreds of good articles on applying OO concepts to JS. JavaScript doesn't have the concept of a class; and I'm fairly convinced trying to force the class concept onto JS adds additional complexity with minimal benefit. Commented Jan 17, 2014 at 21:01
  • I know about OOP in JS, the question is about the best way of using that in AngularJS. I also know that JS does not have classes. changed question title. Commented Jan 18, 2014 at 0:29

1 Answer 1

1

After a discussion started on a google plus angular community post, Dean Sofer gave this good explanation on classing and subclassing on angular: https://gist.github.com/ProLoser/5645860

For your problem, Model should be defined as:

app.factory 'Model', ->
  class Model
    constructor: (blah) ->
      @blah = blah
      @foo   = []
  (blah) ->
    new Model blah

Answering comment #4:

@SET This happens because you are assigning the array to the prototype, somewhat similar to using a static field on a Java class.

Each time you push/pop to that array, you're using the shared prototype array instance.

When you do the same with strings, you're not manipulating a shared instance because javascript strings are immutable. What you are doing is assigning new strings to your object instances (not the prototype anymore).

Heres whats really happening behind the curtain:

Your declarations

foo: []
blah: ''

Converts to:

Model.prototype.blah = '';
Model.prototype.foo = [];

When you manipulate those members, your generated code is (more or less):

a.blah = 'aaa'; // New string on the a object, not on the Model prototype
b.blah = 'bbb'; // New string on the b object, not on the Model prototype

a.foo.push('aaa'); // Push to the foo shared array
b.foo.push('bbb'); // Push to the foo shared array

You can also get what you're trying to do by doing:

a.foo = ['aaa']; // a.foo is a new independent array
b.foo = ['bbb']; // b.foo is a new independent array

But these foos are just hiding the prototype one, that is still there.

Anyway, maybe you should look for more information on javascript's prototypal inheritance.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanx for that. It really helps me. However I still have that problem when array variable inside those objects got linked to some one variable. Please see this plunk
That happens because you are assigning foo on the prototype level. Easily fixable by doing "@foo = []" inside the constructor.
StackOverflow answers are supposed to offer actual content; not links to articles; so I suggest you quote / copy paste the relevant passages from the article into your answer. Read more about that here: stackoverflow.com/help/referencing
@luismreis but why that does not happens to blah variable? Why only arrays affected, where to read about this?
@SET This happens because you are assigning one array to the prototype, somewhat similar to using a static field on a Java.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.