Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何通过ngRepeat“;模板";使用transclude将指令转换为NGO指令?_Javascript_Angularjs_Angularjs Directive_Angularjs Ng Repeat - Fatal编程技术网

Javascript 如何通过ngRepeat“;模板";使用transclude将指令转换为NGO指令?

Javascript 如何通过ngRepeat“;模板";使用transclude将指令转换为NGO指令?,javascript,angularjs,angularjs-directive,angularjs-ng-repeat,Javascript,Angularjs,Angularjs Directive,Angularjs Ng Repeat,演示: 我有一个名为myDirective的ng指令,在指令模板中,我有一个使用ng repeat打印的li标签列表。我想将li标记的内容声明为myDirective声明的一部分,并使用transclude打印所需的text/html内容。通过这种方式,我可以很好地分离关注点,这样我的指令就不需要知道源项的结构,并且调用方负责布局li的内容 如下所示: <my-directive source="vm.source">{{label}} and {{id}}</my-direc

演示:

我有一个名为myDirective的ng指令,在指令模板中,我有一个使用ng repeat打印的li标签列表。我想将li标记的内容声明为myDirective声明的一部分,并使用transclude打印所需的text/html内容。通过这种方式,我可以很好地分离关注点,这样我的指令就不需要知道源项的结构,并且调用方负责布局li的内容

如下所示:

<my-directive source="vm.source">{{label}} and {{id}}</my-directive>
{label}和{{id}
甚至

<my-directive source="vm.source"><a href="#{{id}}">{{label}}</a></my-directive>

ngRepeat(在myDirective内部)的模板如下所示

template: '<ul><li ng-repeat="item in source" ng-transclude></li></ul>',
模板:'
但我无法让转换在hg repeat内部工作。我使用的是angular 1.2.19的最新版本。确切地说,trasnclusion有效,但我在指令级传递的表达式无效

请帮忙,谢谢你

我想不出更好的题目了。欢迎你把它做得更好


更新:我选择了@pixelbits的答案,因为这正是我想要的。但我实际上使用了@Norguard的方法,因为它更具角度。

杰夫,你的转置有点落后

或者,更重要的是,与你认为他们的工作方式相比,他们的工作方式有点落后

如果您有一个transcluding指令,并且将内容放入其中,则内容是从transclude指令的父级读取的,而不是从指令本身读取的

例如,假设:

<div ng-controller="parentController as parent">
    <transcluding-directive>
        {{ key }} {{ val }}
    </transcluding-directive>
</div>
然后,内容将被拉起,并附加到由
transcludingDirective.querySelector(“[ng transclude]”)找到的节点上。

这实际上并不是它的确切工作原理,但它是您得到的结果(在指令中,您不需要执行自己的编译/转置例程)

当您知道第一个错误时,第二个错误会更加明显:
vm
的{label}}和{id}}是
vm
$scope
对象上的属性

它们不存在于
$scope
上,因此
未定义
,这就是从模板中获取
'+'和'+'
的原因。 您正在为传递给指令的每个项创建一个
  • ,但您正在为每个项插入
    未定义的
    未定义的

    您编写的指令应该是一个专门的指令(知道如何构建确切类型的列表的指令)

    
    
    或者是一个通用指令,您可以将列表输入其中

    <generic-drawer>
        <ul><li ng-repeat="item in vm.list">{{item.label}} {{item.id}}</li></ul>
    </generic-drawer>
    
    
    
    • {{item.label}{{{item.id}}
    …它甚至可能是一个特定的指令,知道如何在其模板内提供更通用的指令

     <specific-list items="vm.list"></specific-list>
    
     <!-- specific-list.html -->
     <generic-drawer>
         <generic-toggle ng-repeat="item in items">{{ item.label }} {{ item.id }}</generic-toggle>
     </generic-drawer>
    
    
    {{item.label}{{item.id}
    
    这是Angular(和聚合物,以及将来的Web组件本身)很适合的成分

    作为我一直从事的一个项目的一个简单示例,我有一些元素可以过滤,如下所示:

    <transcluding-directive></transcluding-directive>
    <div>{{ transcludedContent }}</div>
    
    <page-type-a></page-type-a>
    
    <!-- page-type-a.html -->
    <card-collection cards="page.items"></card-collection>
    
    <!-- card-collection.html -->
    <header ><!-- ... header stuff --></header>
    <card ng-repeat="card in cards"></card>
    
    <!-- card.html -->
    <header><h1>{{ title }}</h1></header>
    <blockquote>{{ content }}</blockquote>
    <cite>{{ author }}</cite>
    
    
    <page-type-b></page-type-b>
    <!-- page-type-b.html -->
    <card-collection cards="page.items"></card-collection>
    
    
    {{title}}
    {{content}}
    {{作者}
    
    每个组件只做自己的工作


    还有其他方法可以让它工作(输入一个“key”属性和一个“value”属性,并在将
    $scope
    实例链接到transcluding指令的内部模板之前,从列表中的每个项目中提取值以组成自己的内部列表,用于
    ng repeat
    …或从转置内容中准备值…)…但在这种情况下,这样做听起来很疯狂。

    转包内容是针对父范围的子范围(也称为转包范围,但这与指令的隔离范围不同)编译的。也就是说,您可以在父HTML中指定模板(尽管在angular中它有点超出正常用例),并根据指令的独立范围手动编译它

    HTML

      <body ng-app="myApp">
        <div ng-controller="myController as vm">
          <my-directive source="vm.source">
            <span>{{item.label}} and {{item.id}}</span>
          </my-directive>
        </div>
      </body>
    
    
    {{item.label}和{{item.id}
    
    请注意,我的指令的内部HTML引用了必须在指令范围内定义的“item”

    指令

    function directive($compile) {
        return {
            restrict: 'E',
            scope: {
                source: '='
            },
            compile: function(element, attr) {
              // in the compile phase, remove the contents 
              // of element so that it is not compiled by angular.
              // We will be manually compiling it in the link function.
               var template = angular.element('<ul><li ng-repeat="item in source">' + element.html() + '</li></ul>');
               element.empty();
    
               // link function
               return function(scope, element, attr) {
                 // append the template
                 element.append(template);
    
                 // compile and link the template against the isolated scope.
                 $compile(template)(scope);
               }              
            }          
        };
    }
    
    函数指令($compile){
    返回{
    限制:'E',
    范围:{
    来源:'='
    },
    编译:函数(元素,属性){
    //在编译阶段,删除内容
    //元素,使其不被角度编译。
    //我们将在link函数中手动编译它。
    var template=angular.element('
    • '+element.html()+'
    '); 元素。empty(); //链接功能 返回函数(范围、元素、属性){ //附加模板 元素。追加(模板); //编译模板并将其链接到隔离范围。 $compile(模板)(范围); } } }; }

    Hmmm。。。我想我需要多读一点关于角度的知识。事实上,我有我想要的工作,但方式不同。我将格式化程序函数从控制器传递到指令,该指令为每个li输出所需的格式。但我认为这将是一种更具陈述性的(有角度的)方式来解决我的问题。谢谢你的回答,我会再深入一点,这绝对是可能的。你几乎可以钩住棱角的任何部分,并根据自己的意愿弯曲它。但是,当您编写指令来包装其他指令时,代码会变得简单得多,而不是编写大型预编译或后转置、预链接代码
    function directive($compile) {
        return {
            restrict: 'E',
            scope: {
                source: '='
            },
            compile: function(element, attr) {
              // in the compile phase, remove the contents 
              // of element so that it is not compiled by angular.
              // We will be manually compiling it in the link function.
               var template = angular.element('<ul><li ng-repeat="item in source">' + element.html() + '</li></ul>');
               element.empty();
    
               // link function
               return function(scope, element, attr) {
                 // append the template
                 element.append(template);
    
                 // compile and link the template against the isolated scope.
                 $compile(template)(scope);
               }              
            }          
        };
    }