JSFiddle - React, Tailwind, and code Playground

by Josh Wallace

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.min.js"></script>
<div data-bind="customBinding: shouldBeBound"><p>Here is a great thing...</p></div>
<div id="component-container" data-bind="stopBinding: true">

JavaScript

window.onerror = function(message){
	alert(message);
}

requirejs.config({
    appDir: ".",
    baseUrl: "js",
    paths: { 
        "jquery": "//cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery",
        "knockout": "//cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-debug",
        "text": "//cdnjs.cloudflare.com/ajax/libs/require-text/2.0.12/text.min",
        // <p data-bind="text: message"></p><span display="none" data-bind="template: { afterRender: onRendered() }"></span>
        "component-template": "/echo/js?js=%3Cp%20data-bind%3D%22text%3A%20message%22%3E%3C%2Fp%3E%0A%3Cspan%20display%3D%22none%22%20data-bind%3D%22template%3A%20%7B%20afterRender%3A%20onRendered()%20%7D%22%3E%3C%2Fspan%3E&delay=1"
    }
});

require(["knockout", "jquery"], function(ko, $){
  function CustomBindingController(element){
    var self = this,
    $element = $(element),
    $component,
    shouldDestroy,
    canDestroy,
    destroyComputed;

    function init(){
      $component = $("<!-- ko component: { name: \"my-component\", params: $data } --><!-- /ko -->");

      $("#component-container").append($component);

      ko.applyBindings( { message: "Binding Applied!", onRendered: onComponentRendered }, $component[0]);
			
      shouldDestroy = ko.observable(false);
      canDestroy = ko.observable(false);
			
      destroyComputed = ko.computed(destroy);
      
      self.destroy = function(){ 
      	shouldDestroy(true);
      };
    }

    function destroy(){
    	if(shouldDestroy() && canDestroy()){
      	var $template = $($component.get(0)).nextUntil($component.get(1));
      	$component.remove();
        $template.remove();
        destroyComputed.dispose()
      }
    }

		function onComponentRendered(){
    	canDestroy(true);
    }

    init.call(self);
  }
  
  ko.bindingHandlers.customBinding = {
    update: function(element, valueAccessor){
      var $element = $(element)

      if(ko.unwrap(valueAccessor())){
        $element.data("controller", new...