# Inter-component Relationship

# Defining and Using Inter-component Relationship

Sometimes, you may need to implement components like this:

<custom-ul>
  <custom-li> item 1 </custom-li>
  <custom-li> item 2 </custom-li>
</custom-ul>

In this example, custom-ul and custom-li are custom components that are mutually related and communicate with each other in a complex manner. In this case, we can add the relations definition field when defining components. Example:

Preview with Developer Tool

// path/to/custom-ul.js
Component({
  relations: {
    './custom-li': {
      type: 'child', // The linked target node should be a child node
      linked: function(target) {
        // Executed each time custom-li is inserted. "target" is the instance object of this node, which is triggered after the attached lifecycle of this node.
      },
      linkChanged: function(target) {
        // Executed each time custom-li is moved. "target" is the instance object of this node, which is triggered after the moved lifecycle of this node.
      },
      unlinked: function(target) {
        // Executed each time custom-li is removed. "target" is the instance object of this node, which is triggered after the detached lifecycle of this node.
      }
    }
  },
  methods: {
    _getAllLi: function(){
      // You can get the nodes array via getRelationNodes, including all linked custom-li nodes listed in order
      var nodes = this.getRelationNodes('path/to/custom-li')
    }
  },
  ready: function(){
    this._getAllLi()
  }
})
// path/to/custom-li.js
Component({
  relations: {
    './custom-ul': {
      type: 'parent', // The linked target node should be a parent node
      linked: function(target) {
        // Executed after each insertion to custom-ul. "target" is the instance object of the custom-ul node, which is triggered after the attached lifecycle.
      },
      linkChanged: function(target) {
        // Executed after each move. "target" is the instance object of the custom-ul node, which is triggered after the moved lifecycle.
      },
      unlinked: function(target) {
        // Executed after each removal. "target" is the instance object of the custom-ul node, which is triggered after the detached lifecycle.
      }
    }
  }
})

Note: The relations definition must be added in the definitions of both components. Otherwise, it will be invalid.

# Linking Components of the Same Class

Preview with Developer Tool

Sometimes, you need to link components of the same class. For example:

<custom-form>
  <view>
    input
    <custom-input></custom-input>
  </view>
  <custom-submit> submit </custom-submit>
</custom-form>

The custom-form component wants to link the custom-input and custom-submit components. In this case, if the two components have the same behavior:

// path/to/custom-form-controls.js
module.exports = Behavior({
  // ...
})
// path/to/custom-input.js
var customFormControls = require('./custom-form-controls')
Component({
  behaviors: [customFormControls],
  relations: {
    './custom-form': {
      type: 'ancestor', // The linked target node should be an ancestor node
    }
  }
})
// path/to/custom-submit.js
var customFormControls = require('./custom-form-controls')
Component({
  behaviors: [customFormControls],
  relations: {
    './custom-form': {
      type: 'ancestor', // The linked target node should be an ancestor node
    }
  }
})

Then, in the relations definition, this behavior can be used to replace the component path as the linked target node:

// path/to/custom-form.js
var customFormControls = require('./custom-form-controls')
Component({
  relations: {
    'customFormControls': {
      type: 'descendant', // The linked target node should be a descendant node
      target: customFormControls
    }
  }
})

# relations Definition Field

The relations definition field includes the target component path and its corresponding options. Available options are listed below.

Option Type Required Description
type String Yes The relative relationship of the target component, including parent, child, ancestor, and descendant.
linked Function No A relationship lifecycle function, triggered when the relationship is created in the page node tree after the component's attached lifecycle.
linkChanged Function No A relationship lifecycle function, triggered when the relationship is changed in the page node tree after the component's moved lifecycle.
unlinked Function No A relationship lifecycle function, triggered when the relationship is removed from the page node tree after the component's detached lifecycle.
target String No If this option is set, it indicates a behavior that should be possessed by the linked target node. All component nodes that have this behavior will be linked.