Search code examples
c#angularjsblazorblazor-webassemblyblazor-client-side

Load AngularJS page/controller inside a Blazor Razor Page


My team has a nice-sized AngularJS app that we would like to modernize using Blazor webassembly, and I had assumed that there should be no problem loading a AngularJS controller and page if all the relevant javascript libraries were loaded.

I have successfully gotten everything integrated in a way that I "thought" would work, with the

<body ng-app="testApp">

on the blazor index.html page

and trying to load our basic search via a razor page and the ng-controller tag.

@page "/search"

<div ng-controller="searchCtrl as ctrl">

Amazingly all the angularjs code and libraries seem to load properly and I get no errors in the console. The problem comes when I go to the /search page and AngularJS doesn't seem to recognize the ng-controller tag as the controller itself does not load.

I'm digging into the actual under-the-hood way that blazor deals with javascript libraries but my guess is that angular is loaded but not attached to the "real" DOM and its not getting the events that would let it know that a new page has been loaded.

Note that we are NOT using the angularjs router, but angularjs is supposed to work fine loading the controllers dynamically just from the ng-controller tag.

Anybody have any ideas on things I could try?


Solution

  • Try something like this:

    add to the body of index.html:

    <script type="text/javascript">
        function reinitAngular() {
            var injector = $('[ng-app]').injector();
            var $compile = injector.get('$compile');
            var $rootScope = injector.get('$rootScope');
            $compile(this.$el)($rootScope);
            $rootScope.$digest();
        }
    </script>
    

    within your Razor page/component add:

    @inject IJSRuntime JS;
    
    ...
    
    @code {
        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                await JS.InvokeVoidAsync("reinitAngular");
            }
        }
    }
    

    this will call our js function, which in turn should cause Angular to re-initialize itself. It probably needs to rescan the DOM which was changed by Blazor's own view switching.