无法在AngularJS 1.x中动态加载指令

时间:2016-12-08 09:00:15

标签: javascript angularjs angularjs-directive dynamic-programming

我有很多条件需要动态更改我的视图所以我需要一些方法来改变我的对象,视图会对它做出反应。

我正在尝试使用变量动态加载指令,如下所示:

<body ng-app="myApp" ng-controller="myCtrl">
    <button ng-repeat="type in testDirectiveJson" ng-click="setDirective(type)">{{type}}</button> {{newDirective}}
    <load-directive type="newDirective"></load-directive>
    <script src="./test.directive.js"></script>
</body>

这是我的js

var app = angular.module("myApp", []);
 app.controller('myCtrl', function($scope) {
     $scope.testDirectiveJson = {
         first: '1-directive',
         sec: '2-directive',
         third: '3-directive',
     }
     $scope.lastName = "Doe";
     $scope.newDirective = ""
     $scope.setDirective = function(type) {
         console.log(type);
         $scope.newDirective = type;
         $scope.$apply();
     }
 }).directive("loadDirective", function($compile) {
     return {
         scope: {
             Dtype: '=type'
         },
         link: function(scope, element) {
             var generatedTemplate = '<div ' + scope.Dtype +
                 ' ></div>';
             element.append($compile(generatedTemplate)(scope));
         },
         restrict: 'E'
     };
 }).directive("1Directive", function() {

     return {
         restrict: 'A',
         template: "<h1>Made by a directive A!</h1>"
     };
 }).directive("2Directive", function() {
     return {
         restrict: 'A',
         template: "<h1>Made by a directive! B</h1>"
     };
 }).directive("3Directive", function() {
     return {
         restrict: 'A',
         template: "<h1>Made by a directive! C</h1>"
     };
 });

它没有按预期工作。

如果直接传递指令,它的工作正常。

3 个答案:

答案 0 :(得分:1)

您应该$watch隔离范围Dtype附加html。

link: function(scope, element, attrs) {
             scope.$watch('Dtype', function(newVal) {
                var generatedTemplate = '<div ' + scope.Dtype +
                    ' ></div>';
                  element.html($compile(generatedTemplate)(scope));

             });
         }

此外,您应该从$scope.$apply()方法中移除$scope.setDirective,否则会引发错误$apply already in progress

工作代码

&#13;
&#13;
var app = angular.module("myApp", []);
 app.controller('myCtrl', function($scope) {
     $scope.testDirectiveJson = {
         first: '1-directive',
         sec: '2-directive',
         third: '3-directive',
     }
     $scope.lastName = "Doe";
     $scope.newDirective = ""
     $scope.setDirective = function(type) {
         console.log(type);
         $scope.newDirective = type;
     }
 }).directive("loadDirective", function($compile, $timeout) {
     return {
         scope: {
             Dtype: '=type'
         },
         link: function(scope, element, attrs) {
             scope.$watch('Dtype', function(newVal) {
                var generatedTemplate = '<div ' + scope.Dtype +
                    ' ></div>';
                  element.html($compile(generatedTemplate)(scope));
               
             });
         },
         restrict: 'E'
     };
 }).directive("1Directive", function() {

     return {
         restrict: 'A',
         template: "<h1>Made by a directive A!</h1>"
     };
 }).directive("2Directive", function() {
     return {
         restrict: 'A',
         template: "<h1>Made by a directive! B</h1>"
     };
 }).directive("3Directive", function() {
     return {
         restrict: 'A',
         template: "<h1>Made by a directive! C</h1>"
     };
 });
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
    <button ng-repeat="type in testDirectiveJson" ng-click="setDirective(type)">{{type}}</button> {{newDirective}}
    <load-directive type="newDirective"></load-directive>
    <!--<script src="./test.directive.js"></script>-->
</body>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

如果您希望替换该元素并且在指令内部监视更改,则需要使用html而不是append,因为每次更改单击都需要指令重新编译,如此

 scope.$watch('Dtype', function() {
    var generatedTemplate = '<div ' + scope.Dtype +  ' ></div>';      
    element.html($compile(generatedTemplate)(scope));
 });

请参阅FIDDLE

答案 2 :(得分:0)

链接在指令加载过程中为时已晚,无法动态修改DOM。您需要在预编译阶段进行更改。

请参阅此处有关指令编译的Angular文档:https://docs.angularjs.org/api/ng/service/ $ compile