SPEAK, the HasNestedComponents Property

Recently, some colleagues and MVP reported me some binding errors in SPEAK. All of them was solved by setting the HasNestedComponents property to "true".

The HasNestedComponents is a property you can set on the userControl inside your razor file.

Here is an example:

@{
  var userControl = Html.Sitecore().Controls().GetUserControl(Model.Rendering);

  userControl.HasNestedComponents = true;

  var text = userControl.GetString("Text", "Text");
  var htmlAttributes = userControl.HtmlAttributes;
} 

What is it?

This property is used by SPEAK client-side in order to apply the bindings after the children of a component has been instanciated.

As you know, we use Knockout.js to manage bindings between the DOM and the component object.

In SPEAK, we call the method ko.applyBindings. This method can only be applied once for a DOM node.

Let's take an example. You have a Border component in your page and inside the Border, a Button component.

First, we need to be sure the DOM nodes related to the button are no more candidate for a binding when it has been instanciated. To prevent this, SPEAK provides a custom knockout bindingProvider which prevents knockout applying the bindings twice.

Finally, you need to prevent the ko.applyBindings to be called for the Button before the Border otherwise the bindings defined for the Button will be applied by the Border. This is where you need the HasNestedComponents property. It will prevent the parent component to apply the bindings before the children.

When to use it?

As soon as your component defines Placeholders. If your component defines placholders, it means you can inject other components inside. Therefore, you need to be sure the "parent" component will always apply its own bindings after its children.

Can I always set the HasNestedComponents to true?

No, you can't. If you do that all the components in your page will become container component. This means you will end up with binding errors.

What about the Speak-Technology-Preview layout?

In that version, we have changed the way SPEAK parses the page in order to be more robust and performant. You won't have anymore binding errors if you forget to set it. The HasNestedComponents will now be used to mark the component as a container. By doing that, your component will have direct access to its children in the component object.

Conclusion

Whatever SPEAK version you use, always set the HasNestedComponents to true when you define placeholders inside a component.

comments powered by Disqus