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

Allow to assign object as attribute type (in can.Observe) #107

Closed
whitecolor opened this Issue Sep 17, 2012 · 11 comments

Comments

Projects
None yet
3 participants
@whitecolor
Contributor

whitecolor commented Sep 17, 2012

Currently one can assign model/list name (string) as attribute type for automatic conversion. But if there is no such object in window context (for an example AMD case) it is impossible to do so.

I would propose to use model/list objects it self for declaring attribute type.

steal('can/observe/attributes', 'items.js', function(Observe, Items){
    return Observe({
    attributes: {           
        items: Items // Items is object not 'Items' string
    }
})

then observe knows what type to convert to.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Sep 17, 2012

Contributor

How does it know to call new Items or simply Items? I don't know if this will work.

Contributor

justinbmeyer commented Sep 17, 2012

How does it know to call new Items or simply Items? I don't know if this will work.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Sep 17, 2012

Contributor

You can pass attributes functions. That will work.

Contributor

justinbmeyer commented Sep 17, 2012

You can pass attributes functions. That will work.

@whitecolor

This comment has been minimized.

Show comment
Hide comment
@whitecolor

whitecolor Sep 17, 2012

Contributor

why call just Items, in what case does it make sense?

at list if Items is Construct/Observer or Observe.List/Model.List it does make sense to all new Items, no?

Contributor

whitecolor commented Sep 17, 2012

why call just Items, in what case does it make sense?

at list if Items is Construct/Observer or Observe.List/Model.List it does make sense to all new Items, no?

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Sep 17, 2012

Contributor

attributes:{
items: function(raw){ return new Items(raw) }
}

Sent from my iPhone

On Sep 17, 2012, at 10:29 AM, Alex Osh notifications@github.com wrote:

Currently one can assign model/list name (string) as attribute type for automatic conversion. But if there is no such object in window context (for an example AMD case) it is impossible to do so.

I would propose to use model/list objects it self for declaring attribute type.

steal('can/observe/attributes', 'items.js', function(Observe, Items){

return Observer({
attributes: {

    items: Items // Items is object not 'Items' string

}
})

then observe knows what type to convert to.


Reply to this email directly or view it on GitHub.

Contributor

justinbmeyer commented Sep 17, 2012

attributes:{
items: function(raw){ return new Items(raw) }
}

Sent from my iPhone

On Sep 17, 2012, at 10:29 AM, Alex Osh notifications@github.com wrote:

Currently one can assign model/list name (string) as attribute type for automatic conversion. But if there is no such object in window context (for an example AMD case) it is impossible to do so.

I would propose to use model/list objects it self for declaring attribute type.

steal('can/observe/attributes', 'items.js', function(Observe, Items){

return Observer({
attributes: {

    items: Items // Items is object not 'Items' string

}
})

then observe knows what type to convert to.


Reply to this email directly or view it on GitHub.

@whitecolor

This comment has been minimized.

Show comment
Hide comment
@whitecolor

whitecolor Sep 17, 2012

Contributor

Yes, using function is good, but why not make it automatically.

Contributor

whitecolor commented Sep 17, 2012

Yes, using function is good, but why not make it automatically.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Sep 17, 2012

Contributor

There's no great way to tell a function that is intended to be called with new vs a normal function.

In js a constructor function is just a function. It's how you call it that matters.

Sent from my iPhone

On Sep 17, 2012, at 11:13 AM, Alex Osh notifications@github.com wrote:

why call just Items, in what case does it make sense?

at list if Items is Construct/Observer or Observe.List/Model.List it does make sense to all new Items, no?


Reply to this email directly or view it on GitHub.

Contributor

justinbmeyer commented Sep 17, 2012

There's no great way to tell a function that is intended to be called with new vs a normal function.

In js a constructor function is just a function. It's how you call it that matters.

Sent from my iPhone

On Sep 17, 2012, at 11:13 AM, Alex Osh notifications@github.com wrote:

why call just Items, in what case does it make sense?

at list if Items is Construct/Observer or Observe.List/Model.List it does make sense to all new Items, no?


Reply to this email directly or view it on GitHub.

@justinbmeyer

This comment has been minimized.

Show comment
Hide comment
@justinbmeyer

justinbmeyer Sep 17, 2012

Contributor

Because it's very common to not pass a constructor and a function that might pick between various constructors. Or pass something like Date.parse.

Sent from my iPhone

On Sep 17, 2012, at 11:19 AM, Alex Osh notifications@github.com wrote:

Yes, using function is good, but why not make it automatically.


Reply to this email directly or view it on GitHub.

Contributor

justinbmeyer commented Sep 17, 2012

Because it's very common to not pass a constructor and a function that might pick between various constructors. Or pass something like Date.parse.

Sent from my iPhone

On Sep 17, 2012, at 11:19 AM, Alex Osh notifications@github.com wrote:

Yes, using function is good, but why not make it automatically.


Reply to this email directly or view it on GitHub.

@whitecolor

This comment has been minimized.

Show comment
Hide comment
@whitecolor

whitecolor Sep 17, 2012

Contributor

Ok, it's just proposal. You know better. But for standard objects like Costruct/Observer/Model/List probably it could be done.

Contributor

whitecolor commented Sep 17, 2012

Ok, it's just proposal. You know better. But for standard objects like Costruct/Observer/Model/List probably it could be done.

@daffl

This comment has been minimized.

Show comment
Hide comment
@daffl

daffl Sep 17, 2012

Contributor

I was more thinking along the line of the object providing its own conversion and serialization methods so that you don't have to implement an additional wrapper:

return can.Construct({
    convert : function() {

    },
    serialize : function() {

    }
}, {});

steal('can/observe/attributes', 'items.js', function(Observe, Items){
    return Observe({
    attributes: {           
        items: Items // Items is object not 'Items' string
    }
});

I think #106 is related to that as well (automatic conversion in Observe.List subclasses).

Contributor

daffl commented Sep 17, 2012

I was more thinking along the line of the object providing its own conversion and serialization methods so that you don't have to implement an additional wrapper:

return can.Construct({
    convert : function() {

    },
    serialize : function() {

    }
}, {});

steal('can/observe/attributes', 'items.js', function(Observe, Items){
    return Observe({
    attributes: {           
        items: Items // Items is object not 'Items' string
    }
});

I think #106 is related to that as well (automatic conversion in Observe.List subclasses).

@whitecolor

This comment has been minimized.

Show comment
Hide comment
@whitecolor

whitecolor Sep 18, 2012

Contributor

Yes they (107 and 106) relates. What I propose that if you wnat to get Observe.List named for example Blocks = Block.List (which assumed to be collection of elements of type Block), instead of code:

attributes: {
            items: function(items){
                return new Blocks(items.map(function(item){
                    return new Block(item)
                }))
            }
        }

It would be much more elegant to write just like that:

attributes: {
            items: Blocks
        }
Contributor

whitecolor commented Sep 18, 2012

Yes they (107 and 106) relates. What I propose that if you wnat to get Observe.List named for example Blocks = Block.List (which assumed to be collection of elements of type Block), instead of code:

attributes: {
            items: function(items){
                return new Blocks(items.map(function(item){
                    return new Block(item)
                }))
            }
        }

It would be much more elegant to write just like that:

attributes: {
            items: Blocks
        }
@daffl

This comment has been minimized.

Show comment
Hide comment
@daffl

daffl Oct 16, 2012

Contributor

Hm, GitHub wasn't supposed to close the issue from a branch.

Anyway, @whitecolor check out this branch. The attributes plugin lets you do things like this now:

var Sword = can.Observe({
    getPower : function() {
        return this.attr('power') * 100;
    }
});

var Level = can.Observe({
    getName : function() {
        return 'Level: ' + this.attr('name');
    }
});

var Zelda = can.Observe({
    attributes : {
        sword : Sword,
        levelsCompleted : Level.List
    }
},{});

var link = new Zelda({
    sword : {
        name : 'Wooden Sword',
        power : 0.2
    },
    levelsCompleted : [
        {id: 1, name: 'Aquamentus'},
        {id: 2, name: 'Dodongo'}
    ]
});
Contributor

daffl commented Oct 16, 2012

Hm, GitHub wasn't supposed to close the issue from a branch.

Anyway, @whitecolor check out this branch. The attributes plugin lets you do things like this now:

var Sword = can.Observe({
    getPower : function() {
        return this.attr('power') * 100;
    }
});

var Level = can.Observe({
    getName : function() {
        return 'Level: ' + this.attr('name');
    }
});

var Zelda = can.Observe({
    attributes : {
        sword : Sword,
        levelsCompleted : Level.List
    }
},{});

var link = new Zelda({
    sword : {
        name : 'Wooden Sword',
        power : 0.2
    },
    levelsCompleted : [
        {id: 1, name: 'Aquamentus'},
        {id: 2, name: 'Dodongo'}
    ]
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment