Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependency Observables fail in Collections #32

Closed
cybrox opened this issue May 28, 2015 · 4 comments
Closed

Dependency Observables fail in Collections #32

cybrox opened this issue May 28, 2015 · 4 comments

Comments

@cybrox
Copy link

cybrox commented May 28, 2015

So, I'm not sure if this is actually a problem or if I've missed an important detail here, but I can't seem to find a way to solve it. I created a model following the example of dependency observables and model introduction and it worked just fine.

However, if I do that and push multiple of these models into a collection, the observable is not evaluated correctly anymore.

I'm using the following code:

        var App = blocks.Application();

        var Cake = App.Model({
            cakeType: blocks.observable(),
            cakeSize: blocks.observable(),

            fullCake: blocks.observable(function() {
                return this.cakeType() + 'cake (' + this.cakeSize() + ')';
            })
        })

        var Cakes = App.Collection(Cake);

        App.View('Bakery', {
            cakes: Cakes([
                { cakeType: 'strawberry', cakeSize: 'small' },
                { cakeType: 'chocolate', cakeSize: 'large' }
            ])
        });
    <div data-query="view(Bakery)">
        <div data-query="each(cakes)">
            <h2>Let's eat some, {{fullCake}}!</h2>
            Type: <input data-query="val(cakeType)" />
            <br />
            Size: <input data-query="val(cakeSize)" />
        </div>
    </div>

You would expect this to display Let's eat some, strawberrycake (small) and Let's eat some, chocolatecake (large). However, while the input values are displayed correctly, the dependency obsevable returns Let's eat some, strawberrycake (small) in both entries.
I haven't found a solution for this yet, the error also occurs using {{this.fullCake}} or {{$this.fullCake}}

@astoilkov
Copy link
Owner

Hi,

Yeah. This is actually expected. The reason is fullCake is part of the App.Model prototype. JavaScript prototypes are the same for all objects and do not getted cloned. I am cloning regular observables but not dependency ones. You could resolve your issue by using the code below which creates a new fullCake variable every time a Cake Model is created.

var App = blocks.Application();

var Cake = App.Model({
    cakeType: blocks.observable(),
    cakeSize: blocks.observable(),

    init: function () {
      this.fullCake = blocks.observable(function() {
        return this.cakeType() + 'cake (' + this.cakeSize() + ')';
      }, this);
    }
})

var Cakes = App.Collection(Cake);

App.View('Bakery', {
    cakes: Cakes([
        { cakeType: 'strawberry', cakeSize: 'small' },
        { cakeType: 'chocolate', cakeSize: 'large' }
    ])
});

Additionally, I will leave this issue open to think about if there could be a way to fix the problem.

@cybrox
Copy link
Author

cybrox commented May 28, 2015

Hi

Thanks for the prompt reply!
I got the code working with your solution.

As for solving the problem, I haven't really looked into jsblocks any deeper but spontaneously, I'd say it could be nice having a self-reference in dependency observables that can access the instance data. I'm thinking about not cloning the function prototype but internally passing it a self variable which contains the data of the current context.

For anyone interested, another solution I just figured that I personally like more (at least code-style wise) is using the following code:

var Cake = App.Model({
            cakeType: blocks.observable(),
            cakeSize: blocks.observable(),

            fullCake: function(self) {
                return self.cakeType() + 'cake (' + self.cakeSize() + ')';
            },
});
    <div data-query="view(Bakery)">
        <div data-query="each(cakes)">
            <h2>Let's eat some, {{fullCake($this)}}!</h2>
        </div>
    </div>

@astoilkov
Copy link
Owner

Hmm. Yes. This is interesting idea. I really like how you approached the problem. I will think about it and update you on the status.

Thanks.

@astoilkov
Copy link
Owner

I have fixed the problem. Now you can use the code from your first post and it will work how it is expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants