Skip to content

PROPOSAL: Allow retention of bindings on a read if only values directly on the observable are read #35

@justinbmeyer

Description

@justinbmeyer

I'd like to retain "active" behavior on getters and async getters that only read values directly on their observable. For example:

const SaltShaker = DefineMap.extend({
	saltCount: {
		value({listenTo, resolve}){
			var saltCount = resolve(0);
			listenTo("fill", ()=>{
				resolve(saltCount = 2);
			});
			listenTo("shake", ()=>{
				resolve(--saltCount);
			});
		}
	},
	fill: function(){
		this.dispatch("fill");
	},
	shake: function(){
		let hadSalt = this.saltCount;
		this.dispatch("shake");
		return hadSalt ? "salt" : null;
	},
	get empty() {
		return ! this.saltCount;
	}
});

As saltCount is only listening on an instance of saltShaker, we can leave it bound once someone reads this.saltCount.

The following should work:

const saltShaker = new SaltShaker();

// when read, we notice that the observation is only listening on `saltShaker`:
saltShaker.saltCount;

// Now that saltCount is active, everything works:
saltShaker.fill();  

console.log( saltShaker.shake() ) //-> "salt"
console.log( saltShaker.shake() ) //-> "salt"  
console.log( saltShaker.shake() ) //-> null   

console.log( saltShaker.empty )   //-> true

I think this would be REALLY nice for getters and async getters:

var VM = DefineMap.extend({
  todoId: "number",
  get todoPromise(){
    return Todo.get({id: this.todoId})
  },
  todo: {
    get(lastSet, resolve){
       todoPromise.then(resolve);
    }
  }
});

var vm = new VM({todoId: 5});

vm.todo //-> undefined
setTimeout(function(){
  vm.todo //-> {todo}
},10000)

Obviously, there would still be corner cases like in saltShaker above. But overall, I think these sorts of behaviors would act more like people suspect.

Thoughts?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions