Computed properties with JavaScript Proxy.
const computed = require('computed-proxy')
const person = computed({
lastName: 'Robinson Young',
fullName: computed.property('firstName', 'lastName', {
get (key, previous) {
return `${this.firstName} ${this.lastName}`
}
})
})
person.firstName = 'Kyle'
console.log(person.fullName) // Kyle Robinson Young
person.firstName = 'Crystal'
console.log(person.fullName) // Crystal Robinson Young
const computed = require('computed-proxy')
const restaurant = computed({
food: ['sushi'],
menu: computed.property('food', {
get (key, previous) {
return this.food.join(', ')
}
})
})
console.log(restaurant.menu) // sushi
restaurant.food.push('steak')
console.log(restaurant.menu) // sushi, steak
const computed = require('computed-proxy')
const profile = computed({
person: computed({
name: 'Kyle',
age: 34
}),
howOld: computed.property('person.name', 'person.age', {
get (key, previous) {
return `${this.person.name} is ${this.person.age} years old`
}
})
})
console.log(profile.howOld) // Kyle is 34 years old
profile.person.name = 'Crystal'
profile.person.age = 33
console.log(profile.howOld) // Crystal is 33 years old
const computed = require('computed-proxy')
const restaurant = computed({
food: [
computed({ name: 'sushi', price: 50 })
],
menu: computed.property('food.name', 'food.price', {
get (key, previous) {
return this.food.map(function (item) {
return `${item.name} costs ${item.price}`
}).join(', ')
}
})
})
console.log(restaurant.menu) // sushi costs 50
restaurant.food.push(computed({ name: 'steak', price: 60 }))
console.log(restaurant.menu) // sushi costs 50, steak costs 60
restaurant.food[0].price = 70
console.log(restaurant.menu) // sushi costs 70, steak costs 60
Mark properties as .volatile()
to compute them on every get:
const computed = require('computed-proxy')
const person = computed({
firstName: 'Kyle',
lastName: 'Robinson Young',
fullName: computed.property({
get () {
return `${this.firstName} ${this.lastName}`
}
}).volatile()
})
person.firstName = 'Crystal'
console.log(person.fullName) // Crystal Robinson Young
If you want to manually mark a property to recompute on next get use .notifyPropertChange()
:
const computed = require('computed-proxy')
const person = computed({
firstName: 'Kyle',
lastName: 'Robinson Young',
fullName: computed.property('lastName', {
get (key, previous) {
return `${this.firstName} ${this.lastName}`
}
})
})
console.log(person.fullName) // Kyle Robinson Young
person.firstName = 'Crystal'
// Since fullName isnt bound to firstName, the get doesn't recompute
console.log(person.fullName) // Kyle Robinson Young
person.notifyPropertChange('fullName')
console.log(person.fullName) // Crystal Robinson Young
All properties are read only by default and will throw an error if you try and set them. If you want your property to be settable, provide a set function:
const computed = require('computed-proxy')
const person = computed({
firstName: 'Kyle',
lastName: 'Robinson Young',
upperName: computed.property('firstName', 'lastName', {
get (key, previous) {
return `${this.firstName} ${this.lastName}`.toUpperCase()
},
set (key, val, previous) {
return val.toUpperCase()
}
})
})
console.log(person.upperName) // KYLE ROBINSON YOUNG
person.upperName = 'somebody else'
console.log(person.upperName) // SOMEBODY ELSE
In an environment that doesn't support Proxy
? Shim it by including this in your code:
require('computed-proxy/shim')
(c) 2017 Kyle Robinson Young. MIT License