AngularJS 指令在使用 $.get 加载动态内容后编译

Posted

技术标签:

【中文标题】AngularJS 指令在使用 $.get 加载动态内容后编译【英文标题】:AngularJS directive compile after loading dynamic content with $.get 【发布时间】:2019-08-01 01:36:48 【问题描述】:

我想将内容动态加载到 Angular 应用中。

内容将从 html 模板创建,并且通过 php 加载的数据与 jQuery 的 $.get 函数异步加载。

var app = angular.module('contentApp', []);
app.directive("contentListContainer", function($compile)   
    return 
        link: function($scope, $element) 

            //def
            var templateData1;
            var databaseData;

            //get
            var getTemp1 = $.get("/lib/templateData1.html", function(data, status) 
                templateData1 = data;
            );

            var getData = $.get("/lib/getData.php?type=all", function(data, status) 
                databaseData = JSON.parse(data);
            );

            //build
            $.when(getTemp1, getData).then(function() 
                var uiData = "";

                //combine templates using database Data and build HTML DOM string

                //uiData string example: "<div><div>var1</div><div>var2</div></div>"
                $element.html(uiData);
                $compile($element.contents())($scope); 
            );
        
    
);

最终的 DOM 字符串包含一些我想用角度控制器控制的 表达式。

app.controller('contentCtrl', function($scope) 
    $scope.var1 = 5;
    $scope.var2 = 10;
);

问题:表达式不会被角度控制器编译和使用,它们只显示为纯文本。

【问题讨论】:

与其使用$.get,不如使用$http.get。 AngularJS 通过提供自己的事件处理循环来修改正常的 javascript 流程。这将 JavaScript 拆分为经典和 AngularJS 执行上下文。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等。$.get 方法没有与 AngularJS 框架执行上下文及其摘要循环集成。 【参考方案1】:

不要使用$.get$compile,只需在指令中使用templateUrl 属性即可:

app.directive("contentListContainer", function($compile)   
    return 
        templateUrl: "lib/templateData1.html",
        link: function($scope, $element) 
        
    
)

DEMO on PLNKR

更多信息请见AngularJS Comprehensive Directive API Reference - templateUrl


更新

但我需要在屏幕上显示模板之前对其进行修改,因为模板将根据数据库数据动态更改(加载时)。

不要使用$.get,最好使用$http.get。 $.get 方法未与 AngularJS 框架执行上下文及其摘要循环集成。

app.directive("contentListContainer", function($compile,$http)   
    return 
        //templateUrl: "lib/templateData1.html",
        link: function($scope, $element) 
            var uiData = "";
            $http.get("lib/templateData1.html")
            .then(function(response) 
                uiData = response.data;
                //uiData string example: "<div><div>var1</div><div>var2</div></div>"
                $element.html(uiData);
                $compile($element.contents())($scope);
            );
        
    ;
)

AngularJS 通过提供自己的事件处理循环来修改正常的 JavaScript 流程。这将 JavaScript 拆分为经典和 AngularJS 执行上下文。只有在 AngularJS 执行上下文中应用的操作才能受益于 AngularJS 数据绑定、异常处理、属性监视等。

$compile 可以与$http.get 一起正常工作。

DEMO #2 on PLNKR

【讨论】:

但是我需要在屏幕上显示之前修改模板,因为模板将根据数据库数据动态更改(加载时)。

以上是关于AngularJS 指令在使用 $.get 加载动态内容后编译的主要内容,如果未能解决你的问题,请参考以下文章

如何在angularjs中测试是不是加载指令

需要 angularjs-dragula 包时未加载 angularjs 指令

AngularJS,Node.js,节点模块“幻影”... 注入错误,angularjs 试图加载我的指令 + 后缀

AngularJS指令客户端运行不正常

AngularJS 指令在 <input> 最初加载到 DOM 时隐藏零

Angularjs[26] - 自定义指令(templateUrl)