An Angular (or React / Vue) control inside a coach is a custom coach view that bootstraps the framework on its own DOM element and bridges the coach binding to the component. Recipe for AngularJS (1.x) and the modern equivalent:
- Bundle the framework as a managed web asset (angular.min.js or a webpack bundle of your Angular / React app) and list it in the view's Included scripts. Load it once per page - the coach includes each asset once even if the view is used several times.
- Layout: one root element with a unique id per instance (this.context.viewid is unique per repetition) or use the element reference directly.
- Bootstrap manually in load (not ng-app, which would run before the coach exists), pass the binding in, and write changes back.
// AngularJS 1.x custom coach view - load handler
var _this = this, el = this.context.element;
angular.module("customerCard", []).controller("Ctrl", function ($scope) {
$scope.customer = _this.context.binding.get("value") || {};
$scope.save = function () { _this.context.binding.set("value", angular.copy($scope.customer)); _this.context.trigger(); }; // trigger = boundary event
});
angular.bootstrap(el, ["customerCard"]);
// change handler: when the coach changes the binding, push it into Angular
// var scope = angular.element(el.querySelector("[ng-controller]")).scope(); scope.$apply(function(){ scope.customer = _this.context.binding.get("value"); });// React 18 (bundle exposes window.CustomerCard) - load handler
var _this = this;
_this.root = ReactDOM.createRoot(_this.context.element);
_this.root.render(React.createElement(CustomerCard, { value: _this.context.binding.get("value"), onChange: function (v) { _this.context.binding.set("value", v); } }));
// change handler: _this.root.render(...) with the new value; unload handler: _this.root.unmount();Bridging rules: convert the coach's business object to a plain object (JSON.parse(JSON.stringify(...))) before handing it to the framework, write back with binding.set (never mutate the bound object silently, the coach would not notice), fire context.trigger() for boundary events, and clean up in unload. Keep the framework's CSS scoped to your root element - Bootstrap 3 from the UI Toolkit is on the same page.
References