DoneJS StealJS jQuery ++ FuncUnit DocumentJS
3.0.0
2.3.27

 

  • Github
  • Twitter
  • Chat
  • Forum
  • Guides
  • Core
    • can-component
    • can-compute
    • can-connect
    • can-define
      • static
        • types
      • types
        • PropDefinition
      • behaviors
        • Type
        • Value
        • get
        • serialize
        • set
        • type
        • value
    • 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-define
  • /
  • set
  • / On this page
    • set

      function

      Specify what happens when a property value is set.

      • source

      set( [newVal,] [resolve] )

      A set function defines the behavior of what happens when a value is set on an instance. It is typically used to:

      • Add or update other properties as side effects
      • Coerce the set value into an appropriate action

      The behavior of the setter depends on the number of arguments specified. This means that a setter like:

      prop: {
          set: function(){}
      }
      

      behaves differently than:

      prop: {
          set: function(newVal){}
      }
      

      Parameters

      1. newVal {*}:

        The type function coerced value the user intends to set on the instance.

      2. resolve {function(newValue)}:

        A callback that can set the value of the property asynchronously.

      Returns

      {*|undefined}:

      If a non-undefined value is returned, that value is set as the attribute value.

      If an undefined value is returned, the behavior depends on the number of arguments the setter declares:

      • If the setter does not specify the newValue argument, the property value is set to the type converted value.
      • If the setter specifies the newValue argument only, the attribute value will be set to undefined.
      • If the setter specifies both newValue and resolve, the value of the property will not be updated until resolve is called.

      Use

      A property's set function can be used to customize the behavior of when an attribute value is set. Lets see some common cases:

      Side effects

      The following makes setting a page property update the offset:

      page: {
          set: function(newVal){
              this.offset =  (parseInt(newVal) - 1) * this.limit;
          }
      }
      

      The following makes changing makeId un-define the modelId property:

      makeId: {
          set: function(newValue){
              // Check if we are changing.
              if(newValue !== this.makeId) {
                  this.modelId = undefined;
              }
              // Must return value to set as we have a `newValue` argument.
              return newValue;
          }
      }
      

      Asynchronous Setter

      The following shows an async setter:

      prop: {
          set: function( newVal, setVal){
              $.get("/something", {}, setVal );
          }
      }
      

      Behavior depends on the number of arguments.

      When a setter returns undefined, its behavior changes depending on the number of arguments.

      With 0 arguments, the original set value is set on the attribute.

      MyMap = DefineMap.extend({
          prop: {set: function(){}}
      })
      
      var map = new MyMap({prop : "foo"});
      
      map.prop //-> "foo"
      

      With 1 argument, an undefined return value will set the property to undefined.

      MyMap = DefineMap.extend({
          prop: {set: function(newVal){}}
      })
      
      var map = new MyMap({prop : "foo"});
      
      map.prop //-> undefined
      

      With 2 arguments, undefined leaves the property in place. It is expected that resolve will be called:

      MyMap = DefineMap.extend({
          prop: {
              set: function(newVal, resolve){
                  setVal(newVal+"d");
              }
          }
      });
      
      var map = new MyMap({prop : "foo"});
      
      map.prop //-> "food";
      

      Side effects

      A set function provides a useful hook for performing side effect logic as a certain property is being changed.

      For example, in the example below, Paginator DefineMap includes a page property, which derives its value entirely from other properties (limit and offset). If something tries to set the page directly, the set method will set the value of offset:

      var Paginate = DefineMap.extend({
          limit: 'number',
          offset: 'number',
          page: {
              set: function (newVal) {
                  this.offset = (parseInt(newVal) - 1) * this.limit;
              },
              get: function () {
                  return Math.floor(this.offset / this.limit) + 1;
              }
          }
      });
      
      var p = new Paginate({limit: 10, offset: 20});
      

      Merging

      By default, if a value returned from a setter is an object the effect will be to replace the property with the new object completely.

      var Contact = DefineMap.extend({
          info: {
              set: function(newVal){
                  return newVal;
              }
          }
      })
      
      var alice = new Contact({
          info: {name: 'Alice Liddell', email: 'alice@liddell.com'}
      });
      
      var info  = alice.info;
      
      alice.info = {name: 'Allison Wonderland', phone: '888-888-8888'};
      
      info === alice.info // -> false
      

      In contrast, you can merge properties with:

      Contact = DefineMap.extend({
          info: {
              set: function(newVal){
                  if(this.info) {
                      return this.info.set(newVal);
                  } else {
                      return newVal;
                  }
              }
          }
      });
      
      var alice = new Contact({
          info: {name: 'Alice Liddell', email: 'alice@liddell.com'}
      });
      
      var info  = alice.info;
      
      alice.info = {name: 'Allison Wonderland', phone: '888-888-8888'};
      
      info === alice.info // -> true
      

      Batched Changes

      By default, calls to set methods are wrapped in a call to canBatch.start and canBatch.stop, so if a set method has side effects that set more than one property, all these sets are wrapped in a single batch for better performance.

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