如何动态加载和编译指令?

时间:2015-08-25 13:34:01

标签: javascript angularjs angularjs-directive controller

我在角度js中有一个场景。

我有一个主要下拉列表,项目为“子列表”和“子下拉列表”。我已经使用指令加载了子列表和子下拉列表。

现在我的场景很简单,在从下拉列表中选择子列表时,我想加载'list-directive'并从主下拉列表中选择子下拉列表,我希望结果为'dropdown-的指令“

应该动态发生。

我的Seeddata.js:

var dirType = [
{ text: 'List', value: 0 },
{ text: 'Table', value: 1 },
{ text: 'Dropdown', value: 2 }
];

我的指示

var directiveModule = angular.module('directiveModule', ['serviceModule']);

directiveModule.directive('payerListDirective', function (payerService) {
return {
    restrict :"AC",
    template: "<ul><li ng-repeat='payer in dirType'>{{payer.text}}</li></ul>",
    link: function ($scope) {
        $scope.payersDir = payerService.getPayers();
    }
  };
});
directiveModule.directive('payerDropdownDirective', function (payerService)
{
return {
    restrict: "AC",
    template: "<select ng-model='x' ng-options='payer.value as payer.text for payer in dirType' ></select>",
    link: function ($scope) {
        $scope.payersDir = payerService.getPayers();
    }
};
});

注意:payerService是我从服务模块注入以加载数据的工厂

我的观点

<div ng-controller = "dircntrl" >

<select ng-model = "dirdummy">
<option ng-repeat = "dir in dirType" value = "{{dir.value}}" >{{dir.text}}     </option>
</select>
<div parent-directive></div> // This is the place where I need solution

我的控制器

cntrlModule.controller('dircntrl', function ($scope) {
$scope.dirType = dirType;
$scope.$watch('dirdummy',function(){
    // Want the solution here
})
});

我在控制器中使用 $ watch 来加载结果。但我不知道这样做的确切方法。

2 个答案:

答案 0 :(得分:3)

检查工作演示:JSFiddle

您不需要$watch。使用ng-if动态加载不同的指令。选择一个选项后,将加载相应的指令。

  

注意:ng-if每次都会删除/创建DOM。因此,在选择其他选项后,将删除当前DOM并插入一个全新的DOM元素。

angular.module('Joy', [])
    .controller('JoyCtrl', ['$scope', function ($scope) {
        $scope.choice = '0';
    }])
.directive('firstDirective', function () {
    return {
        restrict: 'A',
        template: '<div>First directive</div>'
    };
})
.directive('secondDirective', function () {
    return {
        restrict: 'A',
        template: '<div>Second directive</div>'
    };
});

HTML:

<div ng-app="Joy" ng-controller="JoyCtrl">
    <select ng-model="choice">
        <option value="0" name="0">Zero</option>
        <option value="1" name="0">One</option>
    </select>
    <div>Selected: {{ choice }}</div>
    <div ng-if="choice==='0'" first-directive></div>
    <div ng-if="choice==='1'" second-directive>Second</div>
</div>

更新1

如果您希望实时编译该指令(虽然不推荐),您可以使用$compile服务来实现它:JSFiddle

关键是:使用ng-change来调用一个函数,该函数编译相应的指令:

var $container = $('#result');
var directiveNames = [
    'payer-list-directive', 
    'payer-dropdown-directive', 
    'payer-dropdown-directive'
];
$scope.changeMe = function () {
    var $ele = $compile('<div ' + directiveNames[$scope.dirdummy] + '></div>')($scope);
    $container.html($ele);
};

在HTML中:

<select ng-model="dirdummy" ng-change="changeMe()">

答案 1 :(得分:0)

以下是 doLogin 点击事件动态加载指令的代码段。在最后一行代码中,将模型div放入正文后启用它。

    var app = angular.module("myapp",)
    app.directive("myLoginModel",function(){
        return {
            restrict:'E',
                template:'login.html',
                controller: 'myLoginController'
        }
    })


    app.controller("myDashboardController",function($compile){

        $scope.doLogin = function($scope){  
            var findTarget = $("body"),
            var compiled = $compile('<my-login-model></my-login-model>')($scope);
            findTarget.append(compiled);
            // Once Login Model directive is compiled and placed inside body section, then
            // enabled Model layout to show.
            setTimeout(function() {
                    $("#loginModel").modal("show");
                    this.$scope.$apply();
            }, 100);
        }
    })