【问题标题】:Is there a way to pass the scope to a directive templateUrl: function?有没有办法将范围传递给指令 templateUrl: 函数?
【发布时间】:2014-06-02 03:52:17
【问题描述】:

我有一个循环调用的指令。循环中的每个项目都有一个 FieldTypeId 属性,并且根据 FieldTypeId 的值,我想换出模板的 URL。我觉得这是一种更好的多态方法,而不是在 html 中执行 ng-switch 语句。

<div ng-repeat="item in attributes">
  <div attribute-input></div>
</div>

当然,$scope 在此指令中不可用:

editStudentAccountModule.directive('attributeInput', function () {
        return {
            restrict: "AE",
            templateUrl: function () { // 
               var attribute = $scope.attributes[$scope.$index];
               if (attribute.FieldTypeId == 1) {
                 return '../Templates/dropdown.html';
               } else if (attribute.FieldTypeId == 2) {
                 return '../Templates/radio.html';
               } // etc.
            }
        }
    });

【问题讨论】:

    标签: angularjs angularjs-directive angularjs-scope


    【解决方案1】:

    您需要在链接函数中加载模板才能访问范围,在此之前您只能在模板或编译中访问模板本身,请查看此处的说明:What are the benefits of a directive template function in Angularjs?

    如果您曾经直接使用过 $compile 服务,这一点就很明显了。当您在某个 DOM 上调用 $compile 时,它​​会返回链接函数,然后您调用该函数传递一个作用域以使其执行。因此,当您从这个角度来看时,很明显,在调用 compile 并返回链接函数然后使用范围调用之前,您将没有范围......它看起来像这样:

    $compile("<div ng-repeat='thing in things'></div>")({things:['thing1','thing2']});//Normally you would pass a scope object in here but it can really be whatever
    

    以下是您的代码在黑暗中的一点点:

    editStudentAccountModule.directive('attributeInput', function () {
            return {
                restrict: "AE",
                scope:{info:"="},
                link: function(scope){
                  var templateToUse = '../Templates/default.html';
                  if (scope.info.FieldTypeId == 1) {
                    templateToUse '../Templates/dropdown.html';
                  } else if (scope.info.FieldTypeId == 2) {
                    templateToUse '../Templates/radio.html';
                  } // etc.
                  scope.myTemplate = templateToUse;
                },
                template:"<div ng-include='myTemplate'></div>";
            }
        });
    
    
    
    <div ng-repeat="item in attributes">
      <div attribute-input info="item"></div>
    </div>
    

    【讨论】:

    • 嗯...我还没有使用 $compile 功能,所以我无法按照您的回答。我正在努力在 AngularJs 中开发一个原型,以确定我们是否应该将 KnockoutJs 转移到 AngularJs 上。
    • 把我上面写的不是一个直接的答案,而只是一些信息,你很可能不想直接使用 $compile 但你可能想使用指令定义对象的 compile: 属性.这两者非常密切相关,因为使用 $compile 服务实际上在标记中查找指令,然后从指令中调用相应的 compile: 属性......编译函数必须返回一个链接函数,然后在传递的范围内调用沿着。
    • 因此,在调用链接函数之前的任何时候(设置模板,调用编译),您还没有范围的句柄。真的,虽然在这种情况下你很可能在这种情况下使用 ng-switch 会好得多,但我真的不明白为什么不这样做。
    • 嗯,这实际上是将模板加载到视图中的部分,ng-include 只是加载一些部分并编译在部分中找到的任何指令,指令定义中的模板预计会返回一个字符串用作模板,除此之外没有做太多其他事情,所以需要使用 ng-include 指令告诉它从模板缓存中加载其他文件并处理它,我们只需要这样做,我们就可以更新字符串在链接函数中使用
    • 如果您想进一步聊天,请加入 #angularjs IRC 房间,通常有人在附近,我有一半时间都在,如果您想直接通知​​我,我的句柄是 wafflejock我并不总是在屏幕上显示它
    猜你喜欢
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    相关资源
    最近更新 更多