如何在Angular中附加指令

时间:2015-12-23 20:45:13

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-ng-repeat

我遇到的问题是附加指令的嵌套无法正常工作。 query-row是一个指令(带有HTML模板),我希望有以下DOM结构

期望的结果

static IAmazonS3 client;


static void DeleteFolderContents(string bucketName, string folderPath) 
{
    using (client = new AmazonS3Client(Amazon.RegionEndpoint.USEast1))
    {
        var allKeys = GetFolderContents(bucketName, fodlerPath);       
        var allDeletes = DeleteAllKeys(bucketName, allKeys);

        // allDeletes has # of deleted objects
    }
}

// using DeleteObjectsRequest (all keys at once)
static int DeleteAllKeys(string bucketName, List<string> allKeys) 
{
    var multiObjectDeleteRequest = new DeleteObjectsRequest();
    multiObjectDeleteRequest.BucketName = bucketName;

    foreach(var key in allKeys)
        multiObjectDeleteRequest.AddKey(key, null); // version ID is null

    try
    {
        var response = client.DeleteObjects(multiObjectDeleteRequest);
        return response.DeletedObjects.Count;
    }
    catch (DeleteObjectsException e)
    {
        // throw exception.
    }

    return 0;
}

// delete one by one
static void DeleteKey(string bucketName, string keyName) 
{
    DeleteObjectRequest deleteObjectRequest = new DeleteObjectRequest
    {
        BucketName = bucketName,
        Key = keyName
    };
    try
    {
        client.DeleteObject(deleteObjectRequest);
    }
    catch (AmazonS3Exception s3Exception)
    {
        // throw
    }
}

// list all keys for a given path
static List<string> 
    GetFolderContents(string bucketName, string folderPath)
{
    var r = new List<string>();

    try
    {
        ListObjectsRequest request = new ListObjectsRequest
        {
            BucketName = bucketName,
            Prefix = folderPath,
            MaxKeys = 100
        };

        do
        {
            ListObjectsResponse response = client.ListObjects(request);

            foreach (S3Object entry in response.S3Objects)
                r.Add(entry.Key);

            // If response is truncated, set the marker to get the next 
            // set of keys.
            if (response.IsTruncated)
                request.Marker = response.NextMarker;
            else
                request = null;
        } while (request != null);
    }
    catch (AmazonS3Exception amazonS3Exception)
    {
        // throw error
    }
}

但我得到的是这个。另见截图

<query-row></query-row>
<query-row></query-row>
<query-row></query-row>
etc...

enter image description here

Javascript代码。正如你在这里看到的那样,在控制器中我创建了一个名为query-row的元素,然后我将它附加到前一个查询行......但是这里我的逻辑是错误的,因为它&# 39; s不附加,而是嵌套在第一个查询行中。

<query-row>
   <query-row></query-row>
   <query-row></query-row>
   etc...
</query-row>

这是一个plnkr http://plnkr.co/edit/1WAgBCEbyk7Tz3fLKnnW

4 个答案:

答案 0 :(得分:0)

回答问题

问题出现在这里:

 angular.element('query-row').append(queryRow)

你可能意味着:

angular.element('query-row').last().after(queryRow)

编辑 - 修改为在@PierraDuc的评论中将queryRow元素放在表单元素中。这会找到最后一个<query-row>元素,然后在其后附加新创建的queryRow元素。

更好的解决方案

但老实说,这非常我建议如何做到这一点。您正在使用视图控制器(queryBuilderCtrl)处理DOM操作。在极端情况下,你应该这样做。您应该在queryBuilderCtrl中设置数组模型对象,其模板使用ng-repeat来处理DOM创建/销毁。

Plunker - http://plnkr.co/edit/k4PUNfeRdeGsxEdruEZi?p=preview

答案 1 :(得分:0)

使用angular.element('query-row').last().after(queryRow)

这是有效的,因为它将首先选择所有query-row个元素。使用函数last(),您将获得最后一个(显然)。使用after(queryRow),您可以将queryRow放在最后query-row元素

之后

正如@jusopi所说,但是控制器中的DOM操作应该减少到最小值

答案 2 :(得分:0)

以下是您修复的示例:http://plnkr.co/edit/DPy8YoaGh1mAAJpFrWE7

我在<div>内添加了新的query-row-wrapperqueryBuilderTemplate.html,因此每个新编译的query-row都会附加到此包装器中。

生成的HTML符合预期。

答案 3 :(得分:0)

拍摄非.append解决方案

http://plnkr.co/edit/i4S3K4JjcTPXkTLT9eOq?p=preview

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

app.controller('myCtrl', ['$scope', function($scope){

  $scope.rows = [{data: 'something'}];
  $scope.add = function() {
    $scope.rows.push({data: 'data1'}); // whatever data goes into a row
  }


}]); 

app.directive('queryBuilder', function() {
  return {
    restrict: 'E',
    scope: {
      rows: "="
    },
    templateUrl: 'queryBuilderTemplate.html',
    link: function(scope, elem, attrs) {
      // do something here?
      console.log( scope.rows );
    }
  }
}).directive('queryRow', function() {
  return {
    restrict: 'EA',
    scope: {
      data: "="
    },
    templateUrl: 'queryRowTemplate.html',
    link: function(scope, elem, attrs) {
        // process data in some way?
        console.log( scope.data )
    }
  }
});

queryBuilderTemplate.html

<div class="queryBuilder">
    <query-row ng-repeat='row in rows' data='row.data'></query-row>
</div>

queryRowTemplate.html

Test {{data}}