Javascript 在指令内使用ng transclude重复ng

Javascript 在指令内使用ng transclude重复ng,javascript,angularjs,Javascript,Angularjs,我想在内容更改时创建一个具有自定义行为的列表。我试图为此创建一个指令,但我对如何将ng TRANCLUDE与ng repeat指令结合起来有点迷茫。有人能让我走上正轨吗 Html: {{myItem}} Javascript: angular.module('myApp', []) .controller('ctrl', function ($scope) { $scope.items = ['one', 'two', 'three']; }) .directive(

我想在内容更改时创建一个具有自定义行为的列表。我试图为此创建一个指令,但我对如何将ng TRANCLUDE与ng repeat指令结合起来有点迷茫。有人能让我走上正轨吗

Html:


{{myItem}}
Javascript:

angular.module('myApp', [])    

.controller('ctrl', function ($scope) {
  $scope.items = ['one', 'two', 'three'];
})    

.directive('mylist', function () {
  return {
    restrict:'E',
    transclude: 'element',
    replace: true,
    scope: true,
    template: [
      '<ul>',
        '<li ng-repeat="WhatGoesHere in items" ng-transclude></li>',
      '</ul>'
    ].join(''),
    link: function (scope, element, attr) {
      var parts = attr.items.split(' in ');
      var itemPart = parts[0];
      var itemsPart = parts[1];
      scope.$watch(itemsPart, function (value) {
        scope.items = value; 
      });      
    }
  }
});
angular.module('myApp',[])
.controller('ctrl',函数($scope){
$scope.items=['1','2','3'];
})    
.directive('mylist',function(){
返回{
限制:'E',
转移:'元素',
替换:正确,
范围:正确,
模板:[
“
    ”, “
  • 中的whatgoesher
  • ”, “
” ].加入(“”), 链接:功能(范围、元素、属性){ var parts=attr.items.split('in'); var itemPart=parts[0]; var itemsPart=零件[1]; 范围.$watch(项spart,函数(值){ scope.items=值; }); } } });
我有一部分工作要做

编辑: 标准:

  • 项的模板必须在视图中定义,而不是在指令中定义,并且它必须能够访问子范围中的项属性。理想情况下,我想定义它,就像在ng repeat指令中一样
  • 指令必须有访问列表的权限,以便我可以设置适当的手表和更改内容。如果可能的话,我希望能够轻松访问生成的DOM项(我也可以使用
    元素[0].querySelectorAll('ul>li')
    或其他什么,它只需要在Chrome上工作)
  • 如果可能的话,我希望重用ng repeat指令中的逻辑,因为它已经做了很多我想要的事情。最好我不想复制代码。我只是想增加它的行为,而不是改变它

不需要转包,因为
包含呈现模板所需的内容。换句话说,元素内部没有任何东西,也就是说,
这里没有什么新的东西,我们需要排除它。看来Angular也能帮我们赚大钱

.directive('mylist', function () {
  return {
    restrict:'E',
    replace: true,
    scope: true,
    template: [
      '<ul>',
      '<li ng-repeat="myItem in items">{{myItem}}</li>',
      '</ul>'
    ].join('')
  }
});
更新:您可以选择创建隔离作用域:

scope: { items: '='},
HTML:


更新2:根据Jan提供的其他信息:

必须在视图中定义项的模板。。。我想重用ng repeat指令中的逻辑

好的,让我们将其全部放在视图中,并使用ng repeat:

<ul mylist>
  <li ng-repeat="myItem in items">
    <span class="etc">{{myItem}}</span>
   </li>
</ul>
  • {{myItem}}
它[指令]必须有权访问子作用域中的项属性。。。指令必须有访问列表的权限,以便我可以设置适当的手表和更改内容

在您最初的fiddle之后,我们将使用一个普通的子作用域(即,子作用域将典型地从父作用域继承):
scope:true,
。这将确保指令可以访问控制器作用域上定义的属性,例如,

对生成的DOM项的访问

指令的链接函数有一个
元素
参数。因此,在上面的HTML中,元素将被设置为
元素。所以我们可以访问所有DOM元素。例如,
element.find('li')
element.children()
。在下面提到的提琴中,我用$watch查看
项目
数组。$watch回调可以访问
元素
,因此您可以访问生成的DOM项。回调将
element.children()
记录到控制台


总之,要将自定义行为添加到列表中,只需将一条指令放到ul或ol上,然后就可以了。

自己解决了这个问题:

在编译步骤()中,我可以通过在编译模板时添加
ng repeat
属性并向其提供我的属性的内容来完成

Html:

{{myItem}}
Javascript:
var myApp=angular.module('myApp',[])
.controller('ctrl',函数($scope){
$scope.items=['1','2','3'];
})
.directive('mylist',function($parse){
返回{
限制:'E',
转移:'元素',
替换:正确,
范围:正确,
模板:[
“
    ”, “
  • ”, “
” ].加入(“”), 编译:函数(远程通讯、tAttrs、转置){ var rpt=document.createAttribute('ng-repeat'); rpt.nodeValue=tAttrs.element; 远程通讯[0]。子项[0]。属性。setNamedItem(rpt); 返回函数(范围、元素、属性){ var rhs=attr.element.split('in')[1]; scope.items=$parse(rhs)(范围); console.log(scope.items); } } } });
实现这一点的另一种方法如下

Index.html:

<html ng-app='myApp'>

<head>
    <title>AngularJS Transclude within Repeat Within Directive</title>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
    <script src='index.js'></script>
</head>

<body ng-controller='myController'>
    <people>Hello {{person.name}}</people>
    <button name="button" ng-click="changeRob()">Change Rob</button>
</body>
</html>

AngularJS Transclude in Repeat in指令
你好{{person.name}
换钱抢劫
index.js:

var myApp = angular.module( 'myApp', [] );

myApp.controller( 'myController', function( $scope ) {
    $scope.people = [
        { name: 'Rob'  },
        { name: 'Alex' },
        { name: 'John' }
    ];

    $scope.changeRob = function() {
        $scope.people[0].name = 'Lowe';
    }
});

myApp.directive( 'people', function() {
    return {
        restrict: 'E',

        transclude: true,
        template: '<div ng-repeat="person in people" transcope></div>',
    }
});

myApp.directive( 'transcope', function() {
    return {
        link: function( $scope, $element, $attrs, controller, $transclude ) {
            if ( !$transclude ) {
                throw minErr( 'ngTransclude' )( 'orphan',
                    'Illegal use of ngTransclude directive in the template! ' +
                    'No parent directive that requires a transclusion found. ' +
                    'Element: {0}',
                    startingTag( $element ));
            }
            var innerScope = $scope.$new();

            $transclude( innerScope, function( clone ) {
                $element.empty();
                $element.append( clone );
                $element.on( '$destroy', function() {
                    innerScope.$destroy();
                });
            });
        }
    };
}); 
var myApp=angular.module('myApp',[]);
控制器('myController',函数($scope){
$scope.people=[
{name:'Rob'},
{name:'Alex'},
{姓名:'约翰'}
];
$scope.changeRob=函数(){
$scope.people[0]。name='Lowe';
}
});
myApp.directive('people',function()){
返回{
限制:'E',
是的,
模板:“”,
}
});
myApp.directive('transcope',function(){
返回{
链接:函数($scope、$element、$attrs、controller、$transclude){
如果(!$transclude){
投掷矿工('ngTransclude')('orphan',
'在模板中非法使用NGTRANCLUDE指令!'+
'未找到需要转换的父指令。'+
'元素:{0}',
startingTag($element));
}
var innerScope=$scope.$new();
$transclude(内部范围,函数(克隆){
<mylist items=items></mylist>
<ul mylist>
  <li ng-repeat="myItem in items">
    <span class="etc">{{myItem}}</span>
   </li>
</ul>
<div ng-app="myApp">
  <div ng-controller="ctrl">
    <mylist element="myItem in items">{{myItem}}</mylist>
  </div>
</div>
var myApp = angular.module('myApp', [])

.controller('ctrl', function ($scope) {
  $scope.items = ['one', 'two', 'three'];
})

.directive('mylist', function ($parse) {
  return {
    restrict:'E',
    transclude: 'element',
    replace: true,
    scope: true,
    template: [
      '<ul>',
      '<li ng-transclude></li>',
      '</ul>'
    ].join(''),
    compile: function (tElement, tAttrs, transclude) {
      var rpt = document.createAttribute('ng-repeat');
      rpt.nodeValue = tAttrs.element;
      tElement[0].children[0].attributes.setNamedItem(rpt);
      return function (scope, element, attr) {
        var rhs = attr.element.split(' in ')[1];
        scope.items = $parse(rhs)(scope);
        console.log(scope.items);
      }        
    }
  }
});
<html ng-app='myApp'>

<head>
    <title>AngularJS Transclude within Repeat Within Directive</title>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js"></script>
    <script src='index.js'></script>
</head>

<body ng-controller='myController'>
    <people>Hello {{person.name}}</people>
    <button name="button" ng-click="changeRob()">Change Rob</button>
</body>
</html>
var myApp = angular.module( 'myApp', [] );

myApp.controller( 'myController', function( $scope ) {
    $scope.people = [
        { name: 'Rob'  },
        { name: 'Alex' },
        { name: 'John' }
    ];

    $scope.changeRob = function() {
        $scope.people[0].name = 'Lowe';
    }
});

myApp.directive( 'people', function() {
    return {
        restrict: 'E',

        transclude: true,
        template: '<div ng-repeat="person in people" transcope></div>',
    }
});

myApp.directive( 'transcope', function() {
    return {
        link: function( $scope, $element, $attrs, controller, $transclude ) {
            if ( !$transclude ) {
                throw minErr( 'ngTransclude' )( 'orphan',
                    'Illegal use of ngTransclude directive in the template! ' +
                    'No parent directive that requires a transclusion found. ' +
                    'Element: {0}',
                    startingTag( $element ));
            }
            var innerScope = $scope.$new();

            $transclude( innerScope, function( clone ) {
                $element.empty();
                $element.append( clone );
                $element.on( '$destroy', function() {
                    innerScope.$destroy();
                });
            });
        }
    };
});