JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.0/angular.min.js"></script>
<div ng-app="app">
    <div ng-controller="Ctrl1">
        <input type="text" ng-model="firstName"/>
        <input type="text" ng-model="lastName"/>
        <ul>
            <li>{{firstName}}</li>
            <li>{{lastName}}</li>
        </ul>
    </div>
        <div ng-controller="Ctrl2">
        <input type="text" ng-model="firstName"/>
        <input type="text" ng-model="lastName"/>
        <ul>
            <li>{{firstName}}</li>
            <li>{{lastName}}</li>
        </ul>
    </div>
</div>

JavaScript

angular.module('Scope.safeApply', []).run(function($rootScope) {

  $rootScope.$safeApply = function() {
    var $scope, fn, force = false;
    if(arguments.length == 1) {
      var arg = arguments[0];
      if(typeof arg == 'function') {
        fn = arg;
      }
      else {
        $scope = arg;
      }
    }
    else {
      $scope = arguments[0];
      fn = arguments[1];
      if(arguments.length == 3) {
        force = !!arguments[2];
      }
    }
    $scope = $scope || this;
    fn = fn || function() { };
    if(force || !$scope.$$phase) {
      $scope.$apply ? $scope.$apply(fn) : $scope.apply(fn);
    }
    else {
      fn();
    }
  };

});

var knockoutBind = function(scope, name, knockoutObservable){
    scope.$watch(name, function(n, o) { knockoutObservable(n);});
    knockoutObservable.subscribe(function(n) { 
        scope.$safeApply(function() {
            scope[name] = n;
        });
    });
};


var app = angular.module('app', ['Scope.safeApply']);

app.controller('Ctrl1', function ($scope, userContext)
{
    $scope.firstName = userContext.firstName();
    $scope.lastName = userContext.lastName();
    
    knockoutBind($scope,"firstName", userContext.firstName);
    knockoutBind($scope,"lastName", userContext.lastName);
});

app.controller('Ctrl2', function($scope, userContext)
{
    $scope.firstName = userContext.firstName();
    $scope.lastName = userContext.lastName();

    knockoutBind($scope,"firstName", userContext.firstName);
    knockoutBind($scope,"lastName", userContext.lastName);
});

var userDataContext = {
    firstName: ko.observable("John"),
    lastName: ko.observable("Doe")
    
};
app.value('userContext', userDataContext);

setTimeout(function() {
    console.log("change firstname");
    userDataContext.firstName("Bart");
}, 3000);