【问题标题】:How to load and compile directives dynamically?如何动态加载和编译指令?
【发布时间】:2015-08-25 13:34:01
【问题描述】:

我在 Angular js 中遇到了一种情况。

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

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

它应该是动态发生的。

我的 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 是我从 Service Module 注入来加载数据的工厂

我的观点

<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 来加载结果。但我不知道执行此操作的确切方法。

【问题讨论】:

    标签: javascript angularjs angularjs-directive controller


    【解决方案1】:

    查看工作演示: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()">
    

    【讨论】:

    • 感谢您的努力。我很欣赏你的方式,甚至我们可以在“ng-switch”的帮助下做到这一点。但问题是,我想动态加载它。我需要放置单个 div,而不是将多个 div 放在一个页面上。希望你能理解我的情况。
    • 在这种情况下,您需要执行以下操作:$compile('&lt;div my-custom-directive-name&gt;&lt;/div&gt;')($scope)。检查$compile。好吧,不建议手动做$compile
    • 是的,这就是我需要的。我的自定义指令名称是什么?我怎样才能做到这一点?
    • 这是你要编译的指令名的变量。根据用户选择,更改值,然后更改$compile
    • 这就是我混淆乔伊的地方。如果可以的话,你能用上面的例子解释一下吗?
    【解决方案2】:

    下面是 doLogin 点击事件动态加载指令的 sn-p 代码。在最后一行代码中,将模型 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);
            }
        })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-27
      • 2019-08-01
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2014-02-27
      相关资源
      最近更新 更多