I’m trying to figure out how to structure the new can-define
technology that allows attr-less
observables.
I see three needs:
- To have something analogous to can.Map (Based on can.Construct)
- To have something that works with normal constructor functions
- To have something that can make observables from POJOs (proxy)
something analogous to can.Map
I think we need to have something that works and looks just like can.Map
except you don’t use .attr()
and there’s no bubbling/change events. In 3.0, everything else will still be Type.extend
.
I’ve thought about something like:
Observable = require("can-observable");
MyObservable = Observable.extend({
init: function(){},
method: function(){},
define: {
prop: { … }
}
});
myo = new MyObservable({prop: "foo"})
myo.on("prop", function(){})
myo.prop = "BAR";
// how to add a new property?
Thoughts:
- I like
Observable
because it’s a noun similar toMap
andList
. -
Observable
is a lot to type compared toMap
andList
. - If somehow we do create a similar
List
variant, what would it be called? - Kinda strange using
Observable
andList
together.
Alternatives:
Defined
-
DMap
- Defined map DefinedMap
-
DefineMap
-require("can-define/map")
-
Observe
- We used to havecan.Observe
-
Model
- Super confusing historically
something that works with normal constructor functions
I’d like people to be able to use Class expressions and make properties observable.
var define = require("can-define");
var Person = class {
constructor(first, last) {
this.first = first;
this.last = last;
}
method(){ }
};
define(Person.prototype, {
first: "*",
last: "*",
fullName: {
get: function() {
return this.first + " " + this.last;
}
}
});
Thoughts:
- I think this is alright. I REALLY wish
class
had some type of extension callback.
something that can make observables from POJOs
We need to take objects and convert them to observables, analogous to:
var obs = new can.Map({foo: "bar"})
There’s two ways we can do this:
- via getter/setters
- via Proxy
Ideally, the API would work with getter/setters and use proxies if they are provided.
Getter/Setters
Getter/Setters allow us two options:
- Mutate the object in place and add “observability” to it.
- Create a new observable object.
Mutate the object in place
We can transform objects to being observable:
var observe = require("can-observe");
var obj = {prop: "FOO"};
observe(obj);
obj.prop = "BAR";
// if you want to add properties:
observe(obj,"newProp","ZED");
obj.on("newProp", function(){ ... });
Create a new observable object.
var Observe = require("can-observe");
var obj = new Observe({prop: "FOO"});
obj.prop
// If you want to add new properties?
Proxy
Proxies don’t really need to work on a particular “type”. They can wrap anything and make it observable:
var observe = require("can-observe");
var obj = observe({prop: "FOO"});
obj.prop
var arr = observe([1,2,3])
arr[0]
Adding properties works automatically.
Thoughts on POJOs:
- proxy works pretty differently than getter/setters to maybe its best not to unify?
- if we don’t unify, do we create them as discrete projects?