注入的 cshtml 文件中的 Angular,$compile 不起作用

Posted

技术标签:

【中文标题】注入的 cshtml 文件中的 Angular,$compile 不起作用【英文标题】:Angular in a injected cshtml file, $compile not working 【发布时间】:2017-05-18 23:33:53 【问题描述】:

TL;TR;在下面

我正在处理一个庞大的应用程序,在该应用程序中,一切都变得超级通用,可以轻松扩展。其中一个组件是对话框。现在,在你的答案是使用ngInclude 或角度模板之前,让我解释一下这些是如何工作的,以及我们为什么要坚持使用它们。

创建此对话框的流程:

    javascript 的某个地方调用一个 javascript 函数。 构造对话框的容器。位置、宽度、高度、灰色背景等。 一旦出现,将显示加载指示器,同时向后端发出 GET 请求。 在后端 Action,提供视图名称和模型。

    这个视图(一个 .cshtml 文件)被加载到一个字符串构建器中。为了让您了解发生了什么,下面是一段加载视图的代码。

    var sb = new StringBuilder(1);
    using (StringWriter sw = new StringWriter(sb))
    
        .....
        var helper = new HtmlHelper(viewContext, viewDataContainer);
        using (helper.BeginForm(null, null, FormMethod.Post, new  enctype = "multipart/form-data" ))
        
            helper.RenderPartial(viewName, model);
        
        return sb.ToString();
    
    

    然后返回字符串,在javascript中最终设置为html:diag.html(jsonResponse.data);

现在我加载的视图包含角度元素,例如 ng-controller 和括号以显示来自该控制器的内容。这是.cshtml:

@model int
<div ng-controller="dialogGridColumnSelectionController as dgc" ng-init="dgc.init(@Model)">

    <table>
        <thead>
           ...
        <tbody>
        <tr ng-repeat="col in dgc.tableColumns">
            <td>
                <input type="checkbox" name="some" ng-value="dgc.hide"/>
            </td>
            <td>col.headerName</td>
            <td>col.Description</td>
        </tr>
        </tbody>
    </table>
</div>

几句话:

ng-app 稍后尝试过,这里应该不需要它,因为 &lt;body&gt; 元素已经有了这个。 对话框位于&lt;body&gt; 元素内。 没有错误,没有角度警告。 col.headerName 显示的完全一样,所以 angular 不起作用。 控制器和所有其他必需的 javascript 文件已加载到打开此对话框的页面上。也尝试在这里添加它们,没有区别。我还尝试再次在那里加载角度,这确实给了我一个警告,我 tried to load it more than once。所以脚本就在那里。

现在我有点怀疑这是否会从一开始就起作用,但我只是想确保在我们开始对对话框进行重大修改之前。

所以我的问题是,这可能吗?从.html()(在javascript中)启动的视图可以有角度吗?我如何“启动”Angular?或者为什么它不适用于生成的 html?

TL;TR 和编辑:

经过一番挖掘,我最终做到了:

dialog.html(jsonResponse.data);//dialog is a created jquery element, jsonResponse.data contains the `.cshtml` content
if (options.angularCompile && options.angularScope) //I've set them in options
    options.angularCompile(dialog)(options.angularScope);//= $compile(dialog)($scope) or $compile(dialog.contents())($scope)

从上面的 html 中,它确实触发了 init 函数。该函数正确加载数据(来自其他注入的工厂)。

var self = this;

this.tablePageID = 0;
this.tableColumns = [];

$scope.hello = "hii";
this.init = function (tablePageID) 
    self.tablePageID = tablePageID;
    self.tableColumns = gridTableFactory.getTableColumns(tablePageID);

但一旦完成并显示对话框,它仍然没有角度工作。

值得注意的是,ng-repeat 一开始就完成了工作,没有项目。看起来它编译并忘记了。

【问题讨论】:

在添加 html 之前使用 $compile。并尝试缩小您的问题范围 - 99% 的问题应该是关于后端或前端的,而不是两者。 最终我的问题是关于前端的。 Angular 在代码中的那部分不可用,但明天我会破解它,看看是否有帮助。 我用过$compile,乍一看似乎可以工作。它编译,执行一些控制器代码,成功使用注入的工厂。但是当对话框打开时,仍然显示纯 html。尖括号不断出现。它有点跑了就忘记了。 当显示对话框时,请验证原始编译的 HTML 是否没有被复制为新的 DOM 元素。对话框打开后,您可能需要运行 $compile 服务。 Hoi Koen,是的,这是最后一件事。事实上,对话框已经显示了一个加载指示器。加载 cshtml 后,它将编辑对话框的内容。 open 事件以 var diag = $(this); 开头。 response.data.html() 应用于现有对话框,然后我 $compile 它。 【参考方案1】:

在使用$compile 后尝试执行$scope.$apply();。您可能需要通知 Angular 以更新其绑定。也尽量避免直接使用 jQuery,而改用angular.element("#....")

【讨论】:

呃,我在角度控制器内部做了$apply(),它说摘要已经很忙,所以我认为不需要它。不需要angular.element() 就可以了。

以上是关于注入的 cshtml 文件中的 Angular,$compile 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

AngularJs将来自单独文件的多个指令注入一个公共模块

Angular 2 中的依赖注入在使用内联注入器和构造器注入时创建多个实例

视图(.cshtml)文件中的编译错误

翻译对比Angular1和Angular2中的依赖注入

ES5 和 ES6 中的 Angular 2 依赖注入

如何使用 Angular 中的依赖注入将属性指令实例传递给嵌套组件