DoneJS StealJS jQuery ++ FuncUnit DocumentJS
3.0.0
2.3.27

 

  • Github
  • Twitter
  • Chat
  • Forum
  • Guides
  • Core
    • can-component
    • can-compute
    • can-connect
      • behaviors
        • ./base/
        • ./cache-requests/
        • ./can/map/
        • ./can/ref/
          • methods
            • init
          • hydrators
            • Map.Ref
        • ./constructor/callbacks-once/
        • ./constructor/
        • ./constructor/store/
        • ./data/callbacks/
        • ./data/callbacks-cache/
        • ./data/combine-requests/
        • ./data/localstorage-cache/
        • ./data/memory-cache/
        • ./data/parse/
        • ./data/url/
        • ./data/worker/
        • ./fall-through-cache/
        • ./real-time/
      • modules
        • ./can/base-map/
        • ./can/model/
        • ./can/super-map/
        • ./can/tag/
        • ./helpers/weak-reference-map
      • data types
        • DataInterface
        • Instance
        • InstanceInterface
        • List
        • ListData
    • can-define
    • can-define/list/list
    • can-define/map/map
    • can-route
    • can-route-pushstate
    • can-set
    • can-stache
    • can-stache/helpers/route
    • can-stache-bindings
  • Ecosystem
  • Infrastructure
  • Legacy
  • Bitovi
    • Bitovi.com
    • Blog
    • Consulting
    • Training
    • Open Source
  • Chat
  • Forum
  • Star
  • Follow @canjs
  • CanJS
  • /
  • Core
  • /
  • can-connect
  • /
  • ./can/ref/
  • / On this page
    • can-connect/can/ref/ref

      module

      Handle references to instances in the raw data returned by the server.

      • source

      canRef( baseConnection )

      Makes a reference type that is loads the related type or hold onto an existing one. This allows us to create circular references and load relevant data as needed

      Parameters

      1. baseConnection {connection}:

        The base connection should have can-connect/can/map/map already applied to it.

      Use

      can/ref is useful when the server might return either a reference to a value or the value itself. For example, in a MongoDB setup, it a request like GET /game/5 might return:

      {
        id: 5,
        teamRef: 7,
        score: 21
      }
      

      But a request like GET /game/5?$populate=teamRef might return:

      {
        id: 5,
        teamRef: {id: 7, name: "Cubs"},
        score: 21
      }
      

      can/ref can handle this abigutity, and even make lazy loading possible.

      To use can/ref, first create a Map and a connection for the referenced type:

      var Team = DefineMap.extend({
          id: 'string'
      });
      
      connect([
        require("can-connect/constructor/constructor"),
        require("can-connect/constructor/store/store"),
        require("can-connect/can/map/map"),
        require("can-connect/can/ref/ref")
      ],{
          Map: Team,
          List: Team.List,
          ...
      })
      

      The connection is necessary because it creates an instance store which will hold instances of Team that the Team.Ref type will be able to access.

      Now we can create a reference to the Team within a Game map and the Game's connection:

      var Game = DefineMap.extend({
       id: 'string',
       teamRef: {type: Team.Ref.type},
       score: "number"
      });
      
      superMap({
        Map: Game,
        List: Game.List
      })
      

      Now, teamRef is a Map.Ref type, which will house the id of the reference no matter how the server returns data like game.teamRef.id.

      For example, without populating the team data:

      Game.get({id: 5}).then(function(game){
          game.teamRef.id //-> 7
      });
      

      With populating the team data:

      Game.get({id: 5, populate: "teamRef"}).then(function(game){
          game.teamRef.id //-> 7
      });
      

      The values of other properties and methods on the Map.Ref type are determined by if the reference was populated or the referenced item already exists in the instanceStore.

      For example, value, which points to the referenced instance will be populated if the reference was populated:

      Game.get({id: 5, $populate: "teamRef"}).then(function(game){
          game.teamRef.value.name //-> 5
      });
      

      Or, it will be populated if that instance had loaded through another means and is in the instance store:

      Team.get({id: 7}).then(function(team){
        // binding adds things to the store
        team.on("name", function(){})
      }).then(function(){
        Game.get({id: 5}).then(function(game){
          game.teamRef.value.name //-> 5
        });
      })
      

      value is an asynchrounos getter, which means that even if the referenced value isn't populated or loaded through the store, it can be lazy loaded. This is generally most useful in a template.

      The following will make an initial request for game 5, but when the template tried to read and listen to game.teamRef.value.name, a request for team 7 will be made.

      var template = stache("{{game.teamRef.value.name}} scored {{game.score}} points");
      Game.get({id: 5}).then(function(game){
         template({game: game});
      });
      

      CanJS is part of DoneJS. Created and maintained by the core DoneJS team and Bitovi. Currently 3.0.0.