如何将指令动态加载到页面中

时间:2014-05-09 04:04:03

标签: angularjs

我有一个带控制器的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中编译代码,动态加载指令,最后加载内容并在范围中追加内容?

1 个答案:

答案 0 :(得分:16)

这是一个通用的模板供您参考摘要,并演示了一些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

的公认答案中考虑动态加载方法的不同观点