【问题标题】:Load AngularJS page/controller inside a Blazor Razor Page在 Blazor Razor 页面中加载 AngularJS 页面/控制器
【发布时间】:2021-02-26 02:08:37
【问题描述】:

我的团队有一个大小合适的 AngularJS 应用程序,我们希望使用 Blazor webassembly 对其进行现代化改造,并且我认为如果加载了所有相关的 javascript 库,加载 AngularJS 控制器和页面应该没有问题。

我已经成功地以我“认为”可行的方式集成了所有内容,使用

<body ng-app="testApp">

在 blazor index.html 页面上

并尝试通过剃须刀页面和 ng-controller 标签加载我们的基本搜索。

@page "/search"

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

令人惊讶的是,所有 angularjs 代码和库似乎都可以正确加载,并且我在控制台中没有任何错误。当我进入 /search 页面时,问题就出现了,AngularJS 似乎无法识别 ng-controller 标签,因为控制器本身没有加载。

我正在深入研究 blazor 处理 javascript 库的实际幕后方式,但我的猜测是 angular 已加载但未附加到“真实”DOM 并且它没有得到让它知道的事件新页面已加载。

请注意,我们没有使用 angularjs 路由器,但 angularjs 应该可以正常工作,仅从 ng-controller 标签动态加载控制器。

有人对我可以尝试的事情有什么想法吗?

【问题讨论】:

  • 更新:我已经能够加载一个控制器,但只能通过将 ng-controller 属性放在 ng-app 的顶层。似乎在初始加载 angularjs 后不知道 dom 更改。如果另一个页面添加了一个带有新 ng-controller 标签的 div,它不会被加载。

标签: c# angularjs blazor blazor-webassembly blazor-client-side


【解决方案1】:

试试这样的:

添加到 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>

在您的 Razor 页面/组件中添加:

@inject IJSRuntime JS;

...

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

这将调用我们的 js 函数,这反过来会导致 Angular 重新初始化自身。它可能需要重新扫描由 Blazor 自己的视图切换更改的 DOM。

【讨论】:

  • 我已经触发了 JS 代码,但是 this.$el 元素为空。查找注入器、$compile 和 $rootScope 的值。在控制台中没有看到错误,但我打赌 this.$el 应该有一些东西。
  • 作为参考,我正在将我正在尝试的回购放在那里:github.com/ExcaliburVT/BlazorAngluarJS
  • 现在是时候了。我避免使用 this.$el 并且只使用 $('[ng-app]') 如果您在页面上放置一个按钮并从中执行 reinitAngular() 页面编译并工作。只需要弄清楚如何延迟编译。
  • 成功!关键是将重新初始化转移到 OnAfterRenderAsync() 如果您可以更新您的示例以反映我在 git 存储库中放置的代码,我会给您信用。
  • ``` function reinitAngular() { console.log('reinitAngular called'); var injector = $('[ng-app]').injector(); var $compile = injector.get('$compile'); var $rootScope = injector.get('$rootScope'); var appElement = $('[ng-app]'); $compile(appElement)($rootScope); $rootScope.$digest(); } ``` ``` @inject IJSRuntime JS; ... @code { protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { await JS.InvokeVoidAsync("reinitAngular"); } } } ```
猜你喜欢
  • 2017-12-30
  • 2020-04-03
  • 2021-11-11
  • 2019-09-18
  • 1970-01-01
  • 2020-08-10
  • 2020-10-22
  • 2021-12-20
  • 1970-01-01
相关资源
最近更新 更多