Creating a component that takes an item or needs to load that item

Someone in bitovi asked:

Can anyone shoot me a link to the canjs pattern for this common scenario:

  1. You have a list component, this component does a request for all items
  2. You have an item component, which gets the data typically passed in from the parent component
  3. If the component isn’t passed in (eg, this component is used as a standalone component), GET the item with that ID <— THIS scenario

Here are some ways that I posted:

itemId: "string",
item: {
  get: function(lastSet, resolve){
    if(lastSet) { return lastSet }
    Item.get({id: this.itemId}).then(resolve)
  }
}

But that doesn’t give you access to the promise, if you need that do:

itemId: "string",
item: Item,
get itemPromise(){
  if(this.itemId) 
    return Item.get({id: this.itemId})
},
get retrievedItem(lastSet, resolve){
  this.itemPromise.then(resolve)
},
get displayItem(){
  return this.item || this.itemPromise
}

w/ 4.0’s value you could do:

itemId: "string",
item: Item,
displayItem: {
  value({listenTo, resolve}) {
    listenTo("item", (ev, item) {
      resolve(item) 
    })
    listenTo("itemId", function(ev, itemId){
      Item.get({id: itemId}).then(resolve)
    })
    if(this.item) resolve(this.item)
  }
}

(that doesn’t give you the promise either)