【问题标题】:How to dynamically load directive into page如何将指令动态加载到页面中
【发布时间】:2014-05-09 12:56:41
【问题描述】:

我有一个带有控制器的 html 文件和一个带有模板 url 的指令。我想在控制器中有条件地加载/编译指令:

控制器:

app.controller('TestController', function TestController($http, $scope, $compile) {

$scope.loadData = function (pageId) {
    var pUrl = <some url>
    $http({
        method: 'GET',
        url: pUrl
    }).success(function (data, status) {
        $scope.pData = data;
        var htm = '<test-directive></test-directive>';
        var elm = angular.element("#id").append(htm);
        $compile(elm)($scope);
    }).error(function (data, status) {
        alert('error');
    });
};

$scope.loadData();

});

指令:

'use strict';

app.directive('testdirective', function ($http) {
var uDirective = {};

uDirective.restrict = 'E';
uDirective.templateUrl = 'js/directives/testdirective.html';
uDirective.controller = function ($scope, $element, $attrs) {
$scope.showDirectiveData();

    $scope.showDirectiveData = function () {
        $scope.directiveDataCollection = <get data>;
    };
};

uDirective.compile = function (element, attributes) {
    // do one-time configuration of element.

    var linkFunction = function ($scope, element, atttributes) {
    };

    return linkFunction;
};

return uDirective;
});

指令中使用的模板

<div>
   <div ng-repeat="directiveData in directiveDataCollection">
      <span><h4>{{directiveData.Title}}</h4></span>
   </div>
</div>

如何在 TestController 中编译代码,动态加载指令,最后加载内容并将内容附加到范围内?

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    这是一个通用模板,供您参考,它抽象并演示了一些 Angular 概念:

    JS

    .directive('parentDirective', function(Resource, $compile){
      return {
        restrict: 'E',
        link: function(scope, elem, attrs){
          Resource.loadData().then(function(result){
            scope.data = result.data;
            var htm = '<child-directive></child-directive>';
            var compiled = $compile(htm)(scope);
            elem.append(compiled);
          });
        }
      }
    })
    .directive('childDirective', function(){
      return {
        restrict: 'E',
        template: '<div>Content: {{data.key}}</div>'
      }
    })
    .factory('Resource', function($http){
      var Resource = {};
    
      Resource.loadData = function(){
        return $http.get('test.json');
      }
    
      return Resource;
    })
    

    HTML

    <body ng-app="myApp">
      <parent-directive></parent-directive>
    </body>
    

    请注意,没有控制器代码。这是因为控制器不应该操纵 DOM - 一个原因是它会使你的代码成为一个要测试的 PITA。因此,我将所有内容都放在指令中,您的情况也应该如此。

    我还将 $http 服务移到了工厂。任何与状态/模型相关的东西都应该在服务中。除其他原因外,通过这样做,您几乎可以在任何地方(包括指令内部)注入它来访问您的数据,而不必担心在控制器卸载时它会消失。

    编辑

    您还应该在接受的Dynamically adding Angular directives答案中考虑一般对动态加载方法的不同看法

    【讨论】:

    • 一个小补充:如果子指令有一个独立的范围并且无法访问父控制器中的 data,您可以简单地重写子模板,如template: '&lt;div content="data"&gt;Content: {{content.key}}&lt;/div&gt;'。很好的解决方案,谢谢@marc-kline!
    • 注意:这仅在子指令显式设置模板 html 时有效。如果您尝试使用 templateURL 或 $http.get 或 $templateRequest 从 URL 加载模板,它将无法正常工作。
    • @nuander 奇怪,加载 templateUrl 使用 Angular 1.5 为我工作
    猜你喜欢
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多