【问题标题】:How to make directive use the controller specified in directive attribute?如何使指令使用指令属性中指定的控制器?
【发布时间】:2021-02-10 17:58:32
【问题描述】:

所以我有一个指令:

<directive data="user" templateUrl="./user.html" controller="UserController"></directive>

我希望该指令使用“控制器”属性中指定的控制器,如上所示。

AngularJS 指令是否可行?或者我应该用其他方式,也许用组件?

我的代码目前如下所示:

app.directive('directive', function() {
        
        var controllerName = "UserController"; // i want that to dynamicaly come from attribute
        
        // check if controller extists:
        var services = [];
        app['_invokeQueue'].forEach(function(value){ 
            services[value[2][0]] = true;
        });         
        if (!services[controllerName]) controllerName = false;
        
        return {
            
            scope: { 'data' : '=' },

            link: function (scope) {
                
                Object.assign(scope, scope.data);
            },
            
            templateUrl: function(element, attr) {
                
                return attr.templateurl;
            },
            
            controller: controllerName
            
        }
        
    });

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-controller


    【解决方案1】:

    您可以执行以下操作(不完全按照您的要求 - 它创建了一堆嵌套范围,但应该足够了):

        .directive('directive', () => {
            scope: { 'data' : '=' },
            template: (elem, attrs) => {
              return '<div ng-controller="' + attrs.controller + ' as vm"><div ng-include="' + attrs.template + '"></div></div>';
            }
        });
    
    <directive data="user" templateUrl="./user.html" controller="UserController"></directive>
    
    • 你可以直接使用 $templateCache 代替 ng-include
    • 如果你需要控制器/模板/...是动态的,你需要观察/观察 + dom 操作 + 重新编译东西

    【讨论】:

      【解决方案2】:

      好的,所以在分析了 Petr 的回答后,我发布了工作代码使用嵌套 div

      app.directive('directive', function() {
              
              return {
                  scope: { 'data' : '=' },
                  
                  link: function (scope) {
                      
                      // this makes your fields available as {{name}} instead of {{user.name}}:
                      Object.assign(scope, scope.data);
                      
                  },
                  
                  template: function(element, attrs) {
                      
                      var controllerName = attrs.controller;
                      var controllerString = controllerName + ' as vm';
                      
                      // check if controller extists:
                      var services = [];
                      app['_invokeQueue'].forEach(function(value){ 
                          services[value[2][0]] = true;
                      })
                      
                      if (!services[controllerName]) {
                          
                          return '<div ng-include="\'' + attrs.templateurl + '\'"></div>'; 
                          
                      } else {
                          
                          return '<div ng-controller="' + controllerString + '"><div ng-include="\'' + attrs.templateurl + '\'"></div></div>';
                              
                      }
                  }
              }
              
          });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-12
        • 2016-03-26
        • 1970-01-01
        • 2016-11-04
        • 2018-03-28
        • 1970-01-01
        相关资源
        最近更新 更多