DoneJS StealJS jQuery++ FuncUnit DocumentJS
4.3.0
5.0.0 3.13.1 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-bind
      • can-compute
      • can-debug
      • can-define
      • can-define/list/list
      • can-define/map/map
      • can-define-backup
      • can-define-stream
      • can-define-stream-kefir
      • can-event-queue
      • can-kefir
      • can-list
      • can-map
      • can-map-define
      • can-observation
      • can-observation-recorder
      • can-observe
      • can-simple-map
      • can-simple-observable
      • can-stream
      • can-stream-kefir
      • can-value
    • Data Modeling
      • can-connect
      • can-connect-feathers
      • can-fixture
      • can-fixture-socket
      • can-ndjson-stream
      • can-set
    • Views
      • can-component
      • can-stache
      • can-stache-bindings
      • can-stache-converters
      • can-stache-route-helpers
      • can-view-autorender
      • can-view-callbacks
      • can-view-import
      • can-view-live
      • can-view-model
      • can-view-nodelist
        • types
          • NodeList
        • methods
          • first
          • last
          • nestList
          • nestReplacements
          • register
          • unregister
          • unregisterChildren
          • update
      • 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-hash
      • can-route-mock
      • can-route-pushstate
    • JS Utilities
      • can-assign
      • can-define-lazy-value
      • can-diff
      • can-globals
      • can-join-uris
      • can-key
      • can-key-tree
      • can-make-map
      • can-parse-uri
      • can-queues
      • can-string
      • can-string-to-any
      • can-util
      • can-zone
      • can-zone-storage
    • DOM Utilities
      • can-ajax
      • can-attribute-encoder
      • can-child-nodes
      • can-control
      • can-dom-data
      • can-dom-events
      • can-dom-mutate
      • can-event-dom-enter
      • can-event-dom-radiochange
      • can-fragment
    • 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-data-types
      • can-namespace
      • can-reflect
      • can-reflect-dependencies
      • 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-view-nodelist

  • npm package badge
  • Star
  • Edit on GitHub

Adds nesting of text nodes

Object

can-view-nodelist is used to make sure nested live-binding sections are able to be cleaned up.

Consider the following template:

<div>
{{#if items.length}}
    Items:
        {{#items}}
            <label></label>
        {{/items}}
    !
{{/if}}
</div>

When items.length value changes to 0, the inner content should be removed and the {{#items}} binding should be torn down.

can-view-nodelist is used to maintain this structure so all nested bindings can be recursively torn down. It's also used to know all the items that need to be removed.

The basic use is

A target is going to be hydrated:

target.hydrate( scope );

This will call the callbacks on placeholder elements.

Those callbacks register their placeholder like this:

nodeLists.register( nodeList = [ placeholderElement ], null );

Then they render the content for the placeholder. This will recursively repeat the same process of hydrating other targets, and registering placeholder elements.

After the content renders, it will call:

// this doesn't actually update the dom. But this will
// detach any "old" nodeLists within `nodeList`
// but oldNodes are all the nodes within the nodeLists
const oldNodes = nodeLists.update(
    nodeList,
    renderedContentFragment.childNodes );

The children calling .update() end up adding to the parent nodeList's .replacements array. nodList might look like:

[
    TEXT_NODE<>  //original placeholder text node
    replacements: [
        [
            <label>
            expression: "items.0"
        ],
        [
            <label>
            expression: "items.1"
        ]
    ]
]

When .update is called on nodeList, the renderedContentFragment will have the final content for what is being rendered. For example, it will be a fragment like:

Items:
<label></label>
<label></label>
!

.update will:

  1. Unregister any child nodeLists previously within nodeList. (there won't be any at this point)
  2. Make a Map of the first node in a replacements nodeList to its nodelist:
    replacementsMap = Map({
        [<label>]: [
            <label>
            expression: "items.0"
        ],
        [<label>]: [
            <label>
            expression: "items.1"
        ],
    })
    
  3. Go through the nodes in renderedContentFragment. If any of them are in the replacementsMap, update nodeList accordingly. nodeList will then look like:
    [
        TEXT_NODE<"Items: ">,
        [
            <label>
            expression: "items.0"
        ],
        [
            <label>
            expression: "items.1"
        ],
        TEXT_NODE<"!">
    ]
    

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

On this page

Get help

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