【问题标题】:How do I assign an attribute to ng-controller in a directive's template in AngularJS?如何在 AngularJS 的指令模板中为 ng-controller 分配一个属性?
【发布时间】:2014-08-14 22:18:08
【问题描述】:

我有一个自定义属性指令(即restrict: "A"),我想将两个表达式(使用{{...}})作为属性传递给指令。我想将这些属性传递到指令的模板中,我用它来呈现两个嵌套的div 标签——外部包含ng-controller,内部包含ng-includeng-controller 将定义专门用于模板的控制器,ng-include 将呈现模板的 HTML。

下面是一个显示相关 sn-ps 的示例。

HTML:

<div ng-controller="appController">
    <custom-directive ctrl="templateController" tmpl="template.html"></custom-directive>
</div>

JS:

function appController($scope) {
    // Main application controller
}

function templateController($scope) {
    // Controller (separate from main controller) for exclusive use with template
}

app.directive('customDirective', function() {
    return {
        restrict: 'A',
        scope: {
            ctrl: '@',
            tmpl: '@'
        },
        // This will work, but not what I want
        // Assigning controller explicitly
        template: '<div ng-controller="templateController">\
                       <div ng-include="tmpl"></div>\
                   </div>'
        // This is what I want, but won't work
        // Assigning controller via isolate scope variable from attribute
        /*template: '<div ng-controller="ctrl">\
                         <div ng-include="tmpl"></div>\
                     </div>'*/
    };
});

似乎显式分配控制器有效。但是,我想通过一个隔离范围变量来分配控制器,该变量是从位于 HTML 中的自定义指令内的属性中获得的。

我在下面的 Plunker 中进一步充实了上面的示例,它将相关指令命名为 contentDisplay(而不是上面的 customDirective)。如果此示例需要更多注释说明,请在 cmets 中告诉我:

Plunker

使用显式控制器分配(未注释的模板代码),我实现了所需的功能。但是,当尝试通过隔离范围变量(注释模板代码)分配控制器时,它不再起作用,并抛出错误消息 'ctrl' is not a function, got string

我想要改变控制器的原因(而不是像我在 Plunker 中所做的那样将所有控制器放入一个“主控制器”)是因为我想让我的代码更有条理以保持可读性。

以下想法可能是相关的:

  • ng-controller 标签放在模板内,而不是将其包裹在ng-include 周围。
  • 使用单向绑定 ('&amp;') 代替文本绑定 ('@') 来执行函数。
  • 除了隔离作用域之外,使用链接函数代替 /。
  • 使用元素/类指令而不是属性指令。
  • ng-controller的优先级低于ng-include
  • 编译/实例化指令的顺序可能不正确。

虽然我正在寻找此问题的直接解决方案,但我也愿意接受完成相同功能且相对简单的变通方法。

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-controller angularjs-ng-include


    【解决方案1】:

    我认为您不能使用scope 动态编写template 密钥,但您当然可以在link 函数中这样做。您可以使用一系列内置 Angular 函数非常简洁地模仿:$http$controller$compile$templateCache

    Plunker

    相关代码:

        link: function( scope, element, attrs )
        {
          $http.get( scope.tmpl, { cache: $templateCache } )
            .then( function( response ) {
              templateScope = scope.$new();
              templateCtrl = $controller( scope.ctrl, { $scope: templateScope } );
              element.html( response.data );
              element.children().data('$ngControllerController', templateCtrl);
              $compile( element.contents() )( templateScope );
            });
        }
    

    受到this similar answer的强烈启发。

    【讨论】:

    • 感谢您的解决方法!一个后续问题:您提到“template 可能没有足够的权限访问scope”——一个组件怎么可能只有部分访问scope?不应该是全有还是全无?用更具体的例子来说,tmpl 如何可以通过template 键访问,而不是ctrl
    • 抱歉,有点不清楚,我只是说我不知道​​如何制作像'&lt;div ng-controller="' + scope.tmpl +'" /&gt;' 这样的字符串。 (注意对scope 的引用;在普通的template 字符串中,您可以让Angular 在内部处理每个范围属性。
    猜你喜欢
    • 2016-01-23
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多