DoneJS StealJS jQuery++ FuncUnit DocumentJS
3.14.1
5.0.0 4.3.0 2.3.35
  • About
  • Guides
  • API Docs
  • Community
  • Contributing
  • Bitovi
    • Bitovi.com
    • Blog
    • Design
    • Development
    • Training
    • Open Source
    • About
    • Contact Us
  • About
  • Guides
  • API Docs
    • Observables
      • can-compute
      • can-define
      • can-define/list/list
      • can-define/map/map
      • can-define-stream
      • can-define-stream-kefir
      • can-event
      • can-event/async/async
      • can-event/batch/batch
      • can-event/lifecycle/lifecycle
      • can-kefir
      • can-list
      • can-map
      • can-map-backup
      • can-map-define
      • can-observation
      • can-observe
      • can-simple-map
      • can-simple-observable
      • can-stream
      • can-stream-kefir
    • Data Modeling
      • can-connect
        • behaviors
          • ./base/
          • ./cache-requests/
          • ./can/constructor-hydrate/
          • ./can/map/
          • ./can/merge/
          • ./can/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/map-deep-merge
          • ./helpers/weak-reference-map
        • data types
          • DataInterface
          • Instance
          • InstanceInterface
          • List
          • ListData
      • can-connect-cloneable
      • can-connect-feathers
      • can-connect-ndjson
      • can-connect-signalr
      • can-fixture
      • can-fixture-socket
      • can-ndjson-stream
      • can-set
    • Views
      • can-component
      • can-ejs
      • can-element
      • can-react-component
      • can-stache
      • can-stache/helpers/route
      • can-stache-bindings
      • can-stache-converters
      • can-view-autorender
      • can-view-callbacks
      • can-view-href
      • can-view-import
      • can-view-live
      • can-view-model
      • can-view-nodelist
      • can-view-parser
      • can-view-scope
      • can-view-target
      • react-view-model
      • react-view-model/component
      • steal-stache
    • Routing
      • can-deparam
      • can-param
      • can-route
      • can-route-pushstate
    • JS Utilities
      • can-assign
      • can-define-lazy-value
      • can-globals
      • can-key-tree
      • can-make-map
      • can-parse-uri
      • can-string
      • can-string-to-any
      • can-util
      • can-zone
      • can-zone-storage
    • DOM Utilities
      • can-ajax
      • can-attribute-encoder
      • can-control
      • can-dom-events
      • can-event-dom-enter
      • can-event-dom-radiochange
      • can-jquery
    • Data Validation
      • can-define-validate-validatejs
      • can-validate
      • can-validate-interface
      • can-validate-legacy
      • can-validate-validatejs
    • Typed Data
      • can-cid
      • can-construct
      • can-construct-super
      • can-namespace
      • can-reflect
      • can-reflect-promise
      • can-types
    • Polyfills
      • can-symbol
      • can-vdom
    • Core
    • Infrastructure
      • can-global
      • can-test-helpers
    • Ecosystem
    • Legacy
  • Community
  • Contributing
  • GitHub
  • Twitter
  • Chat
  • Forum
  • News
Bitovi

can-connect/can/model/model

  • Edit on GitHub

Exports a constructor that works very similar to can.Model.

Model.extend( static, prototype )

Defines a can-map that has almost all of the functionality of can.Model.

Use

can-connect/can/model is for backwards compatibility with can.Model so that developers can migrate to can-connect without having to rewrite their models immediately.

However, use of can.Model will be deprecated in CanJS 3.0. Instead of extending can.Model, extend can-map and can-list and use the can/map behavior to connect your Map and List to a connection:

var CanMap = require("can-map");
var CanList = require("can-list");

var Todo = CanMap.extend({ ... });

var TodoList = CanList.extend({
  Map: Todo
},{ ... });

var todoConnection = connect(["data-url","constructor","can/map"],{
  Map: Todo,
  List: TodoList,
  url: "/services/todos"
});

Or, use the can-connect/can/super-map/super-map function to create a connection with the "super" behaviors:

var todoConnection = superMap({
  idProp: "_id",
  Map: Todo,
  List: TodoList,
  url: "/services/todos",
  name: "todo"
});

For your legacy code, you should just need to import "can-connect/can/model/" instead of "can/model/" like:

import Model from "can-connect/can/model/";

Todo = Model.extend({
  findAll: "/todos"
},{});

Todo.findAll({}).then(function(todos){

});

Upgrading can.Models to can-connect

This section walks through making the necessary changes to upgrade a legacy can.Model to use can-connect and its behaviors. We'll convert a can.Model and can.Model.List that looks like:

Todo = can.Model.extend({
  resource: "/",
  destroy: "POST /todos/{id}/delete",
  findOne: function(params){
    return $.get("/todos/"+params._id);
  },

  parseModels: function(data){
    return data.todos;
  },
  parseModel: "todo",

  id: "_id",
},{
  method: function(){ ... },
  define: { ... }
});

Todo.List = Todo.List.extend({ ... });

Converting this to use can-connect looks like:

var CanMap = require("can-map"),
    CanList = require("can-list");

Todo = CanMap.extend({
  method: function(){ ... },
  define: { ... }
});
Todo.List = CanList.extend({
  Map: Todo
},{ ... })

connect([
    require("can-connect/data/url/url"),
    require("can-connect/data/parse/parse"),
    require("can-connect/constructor/constructor"),
    require("can-connect/constructor/store/store"),
    require("can-connect/can/map/map")
  ],
  {
    Map: Todo,
    List: Todo.List,

    url: {
      resource: "/",
      destroyData: "POST /todos/{id}/delete",
      getData: function(params){
        return $.get("/todos/"+params._id);
      }
    },

    parseListData: function(data){
      return data.todos;
    },
    parseInstanceProp: "todo",

    idProp: "_id"
  });

Instead of Todo.findAll and Todo.findOne, use Todo.getList and Todo.get.

Lets break this down in the following sections.

Defining the Map and List

The first step is to pull out the parts of the Model and Model.List that define the observable Map and List's behavior into a can-map and can-list:

var CanMap = require("can-map"),
    CanList = require("can-list");

Todo = CanMap.extend({
  method: function(){ ... },
  define: { ... }
});
Todo.List = CanList.extend({
  Map: Todo
},{ ... })

One of the main advantageous of can-connect is that it lets separate persistence behavior from property behavior.

Connecting the Map and List to behaviors

The next step is to connect the Map and List to the right behaviors. The following adds behaviors with similar functionality to legacy can.Map and uses the can/map behavior (which makes use of constructor) to connect the connection to the provided Map and List types:

connect([
    require("can-connect/data/url/url"),
    require("can-connect/data/parse/parse"),
    require("can-connect/constructor/constructor"),
    require("can-connect/constructor/store/store"),
    require("can-connect/can/map/map")
  ],
  {
    Map: Todo,
    List: Todo.List,
    ...
  })

Connecting to urls

The data/url behavior supports CRUDing data from urls. It can be configured like:

connect(["data-url", ...],
  {
    ...
    url: {
      resource: "/",
      destroyData: "POST /todos/{id}/delete",
      getData: function(params){
        return $.get("/todos/"+params._id);
      }
    },
    ...
  });

Correcting response data

The can-connect/data/parse/parse behavior supports correcting response data. It can be configured like:

connect([..., "data-parse", ...],
  {
    ...
    parseListData: function(data){
      return data.todos;
    },
    parseInstanceProp: "todo",
    ...
  });

Specifying the id

The id of a model is used in a variety of ways. It's part of the base behavior added to every connection. You can customize which property represents the id with idProp.

connect([...],
  {
    idProp: "_id"
  });

Retrieving data

The can/map behavior adds a getList and get method to the Map option. Use them in place of findAll and findOne:

Todo.findAll({}).then(function(todosList){ ... });
Todo.findOne({id: 5}).then(function(todo){ ... });

Differences from can.Model

Model's produced from can-connect/can/model:

  • Do not support makeFindAll or makeFindOne. If your legacy code did this, you can probably add it as a custom behavior.
  • Has the instance store at Model.store, but items should be retrieved like Model.store.get(id).
  • Should not use Model.models or Model.model to correct Ajax data and should instead use Models.parseModel and Model.parseModels.
  • Uses a Promise polyfill, not jQuery's promises.

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

On this page

Get help

  • Chat with us
  • File an issue
  • Ask questions
  • Read latest news