Object
Create observable key-value instances or types.
new observe.Object(properties)
Create an instance of an observable object.
import observe from "can-observe";
const person = new observe.Object( { name: "Frank Castle" } );
Unlike observe({name: "Frank Castle"})
, person
will
have mixed-in methods and properties like .on
and
.off
available.
class extends observe.Object {...}
Extend and create your own Object
type:
import observe from "can-observe";
class Person extends observe.Object {
get fullName() {
return this.first + " " + this.last;
}
}
Getter properties like fullName
above are computed. Meaning that if they are bound
subsequent reads are not re-evaluated.
Instances of Person
will
have mixed-in methods and properties like .on
and
.off
available.
Mixed in methods and properties
Instances of observe.Object
have all methods and properties from
can-event-queue/map/map:
addEventListener - Register an event handler to be called when an event is dispatched.
@can.getWhatIChange - Return observables whose values are affected by attached event handlers
@can.isBound - Return if the observable is bound to.
@can.offKeyValue - Unregister an event handler to be called when an event is dispatched.
@can.onKeyValue - Register an event handler to be called when a key value changes.
dispatch - Dispatch event and key binding handlers.
listenTo - Listen to an event and register the binding for simplified unbinding.
off - A shorthand method for unbinding an event.
on - A shorthand method for listening to event.
one - Register an event handler that gets called only once.
removeEventListener - Unregister an event handler to be called when an event is dispatched.
stopListening - Stops listening for registered event handlers.
Example:
class MyObject extends observe.Object {
}
const instance = new MyObject( {} );
canReflect.onPatches( instance, function( patches ) { /* ... */ } );
Mixed-in type methods and properties
Extended observe.Object
constructor functions have all methods and properties from
can-event-queue/type/type:
@can.offInstanceBoundChange - Stop listening to when an instance's bound status changes.
@can.offInstancePatches - Stop listening to patch changes on any instance.
@can.onInstanceBoundChange - Listen to when any instance is bound for the first time or all handlers are removed.
@can.onInstancePatches - Listen to patch changes on any isntance.
Example:
class MyObject extends observe.Object {
}
canReflect.onInstancePatches( MyObject, function( instance, patches ) { /* ... */ } );
Use Cases
observe.Object
is used to make observable models and view-models.
ViewModels
Use observe.Object
to create view-models for use with can-component. The following
creates a TodoListVM
and and uses it with the todo-list
component:
class TodoListVM extends observe.Object {
isEditing( todo ) {
return todo === this.editing;
}
edit( todo ) {
this.backupName = todo.name;
this.editing = todo;
}
cancelEdit() {
if ( this.editing ) {
this.editing.name = this.backupName;
}
this.editing = null;
}
updateName() {
this.editing.save();
this.editing = null;
}
}
Component.extend( {
tag: "todo-list",
view,
ViewModel: TodoListVM
} );
Special behaviors
observe.Object
lacks many of the extended features of can-define. This means you often need to
add this behavior manually.
When simple getters
can be used, use connectedCallback to update properties based on other
values. The following keeps todosList
updated with changes in todosPromise
:
class AppVM extends observe.Object {
get todosPromise() {
if ( !this.filter ) {
return Todo.getList( {} );
} else {
return Todo.getList( {
complete: this.filter === "complete"
} );
}
}
connectedCallback() {
this.listenTo( "todosPromise", ( promise ) => {
promise.then( ( todos ) => {
this.todosList = todos;
} );
} );
this.todosPromise.then( ( todos ) => {
this.todosList = todos;
} );
return this.stopListening.bind( this );
}
}
If you'd like a property to be non-enumerable, you need to define this during
initialization of your instance within constructor
. The following makes
todosList
non-enumerable:
class AppVM extends observe.Object {
constructor( props ) {
super( props );
Object.defineProperty( this, "todosList", {
enumerable: false,
value: null,
configurable: true,
writable: true
} );
}
}
Models
Use observe.Object
to create observable view-models for use
with can-connect. The following creates a simple Todo
type:
import observe from "can-observe";
import baseMap from "can-connect/can/base-map/base-map";
class Todo extends observe.Object {
updateName( newName ) {
this.name = newName;
this.updatedAt = new Date().getTime();
}
}
baseMap( {
url: "/api/todos",
Map: Todo
} );