将动态内容添加到角度js中的动态创建内容

时间:2014-04-10 14:33:15

标签: jquery angularjs ionic-framework

我希望像树形结构一样展示购物车类别。当我单击父ul>li元素时,它从服务器获取数据并动态添加新数据集。我有n级,最初当我点击第一级时,我创建了一个动态子集,并使用其类名将其放在父级下。为新创建的子节点调用相同的函数,但这次更新了单击元素的超级父节点。我已经创建了plunker以获得详细解释。

当我点击men类别时,其子元素将填充:

  • 男士腕表
  • 衬衫

当我点击"男士"时,它应该添加下面的下一级 - 但它过度写了现有的数据。

请帮帮我。我是棱角分明的新人。

HTML:

<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.3/angular.js"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <ul class="navigation">
    <li ng-repeat='category in fullTree.category[0]' ng-class='category.category_id' ng-click='dropmenu(category.category_id,category.level,category.has_child_category,$event);event.stopImmediatePropagation()'>
      <p>{{category.category_name}} <i class="ion-chevron-down"></i>
      </p>
    </li>
  </ul>
</body>

</html>

脚本:

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

app.controller('MainCtrl', function($scope, $sce, $compile) {
  $scope.name = 'World';
  $scope.html = "";

  $scope.htmlElement = function() {
    var html = "<input type='text' ng-model='html'></input>";
    return $sce.trustAsHtml(html);
  }

  $scope.fullTree = {
    "result": "true",
    "success": 1,
    "category": [
      [{
        "category_id": "prdcat01",
        "category_name": "Men",
        "level": "1",
        "higher_level_catg_no": "0",
        "total_level": "3",
        "has_child_category": "true",
        "total_product": "0"
      }, {
        "category_id": "prdcat02",
        "category_name": "Women",
        "level": "1",
        "higher_level_catg_no": "0",
        "total_level": "3",
        "has_child_category": "true",
        "total_product": "0"
      }, {
        "category_id": "prdcat03",
        "category_name": "Kids",
        "level": "1",
        "higher_level_catg_no": "0",
        "total_level": "1",
        "has_child_category": "false",
        "total_product": "0"
      }],
      [{
        "category_id": "cat01c01",
        "category_name": "Wrist Watch For Men",
        "level": "2",
        "higher_level_catg_no": "prdcat01",
        "has_child_category": "true",
        "total_product": "1"
      }, {
        "category_id": "cat02c01",
        "category_name": "Wrist Watch For Women",
        "level": "2",
        "higher_level_catg_no": "prdcat02",
        "has_child_category": "true",
        "total_product": "0"
      }, {
        "category_id": "cat01c02",
        "category_name": "Shirt for men",
        "level": "2",
        "higher_level_catg_no": "prdcat01",
        "has_child_category": "false",
        "total_product": "0"
      }, {
        "category_id": "cat02c02",
        "category_name": "Shirt For Women",
        "level": "2",
        "higher_level_catg_no": "prdcat02",
        "has_child_category": "false",
        "total_product": "0"
      }],
      [{
        "category_id": "cat0101c01",
        "category_name": "Fastrack Watch For Men",
        "level": "3",
        "higher_level_catg_no": "cat01c01",
        "has_child_category": "false",
        "total_product": "0"
      }, {
        "category_id": "cat0201c01",
        "category_name": "Fastrack Watch For Women",
        "level": "3",
        "higher_level_catg_no": "cat02c01",
        "has_child_category": "false",
        "total_product": "1"
      }, {
        "category_id": "cat0101c02",
        "category_name": "Casio watch for men",
        "level": "3",
        "higher_level_catg_no": "cat01c01",
        "has_child_category": "false",
        "total_product": "1"
      }]
    ],
    "msg": "Data retrieved successfuly"
  };

  $scope.dropmenu = function(category_id, level, has_child_category, $event) {
    $event.stopPropagation();

    $scope.dummy = [];

    for (var i = 0; i < $scope.fullTree.category[level].length; i++) {
      if ($scope.fullTree.category[level][i].higher_level_catg_no == category_id) {
        $scope.dummy.push($scope.fullTree.category[level][i]);
      }
    }

    alert(JSON.stringify($scope.dummy))

    var fieldHtml = "<ul class='navigation'><li ng-class={{category.category_id}} ng-repeat='category in dummy' ng-click='dropmenu(category.category_id,category.level,category.has_child_category,$event);event.stopPropagation()'><p>{{category.category_name}} <i class='ion-chevron-down'></i></p></li></ul>";

    var compiledElement = $compile(fieldHtml)($scope);

    $($event.target).closest("." + category_id).append(compiledElement);
  }
});

2 个答案:

答案 0 :(得分:2)

更新未知级别数
您可以将我为3个级别中的每个级别编写的内容概括为模板,并递归地使用它来处理任意数量的子类别级别。

template.html:

<ul ng-show="$parent.category.expand" class="navigation" ng-init="level = $parent.level+1">
  <li ng-repeat="category in fullTree.category[level]" ng-if="category.higher_level_catg_no == $parent.category.category_id" ng-class="category.category_id">
    <p>{{category.category_name}}
      <i ng-click="category.expand = !category.expand" class="ion-chevron-down"></i>
    </p>
    <ng-include src="'template.html'" ng-if="fullTree.category[level+1]"></ng-include>
  </li>
</ul>

index.html中有一点重复,可能会在更多考虑设置的情况下消除。但这有效,并且不需要任何DOM操作。

以下是更新的演示:http://plnkr.co/edit/DJ3hXHwYmf3n1LHArzWn?p=preview


3 级别的原始答案

我建议您阅读这个问题:"Thinking in AngularJS" if I have a jQuery background?

您可以嵌套ng-repeat来创建列表结构,而不是尝试在控制器中构建DOM,然后不得不使用jQuery编译和插入它。然后使用ng-if在单击父类别时呈现子类别。

<ul class="navigation">
  <li ng-repeat="category in fullTree.category[0]" ng-class="category.category_id">
    <p>{{category.category_name}}
      <i ng-click="category.expand = !category.expand" class="ion-chevron-down"></i>
    </p>
    <ul ng-if="category.expand" class="navigation">
      <li ng-repeat="subcategory in fullTree.category[1]" ng-if="subcategory.higher_level_catg_no == category.category_id">
        <p>{{subcategory.category_name}}
          <i ng-click="subcategory.expand = !subcategory.expand" class="ion-chevron-down"></i>
        </p>
        <ul ng-if="subcategory.expand" class="navigation">
          <li ng-repeat="subcategory2 in fullTree.category[2]" ng-if="subcategory2.higher_level_catg_no == subcategory.category_id">
            <p>{{subcategory2.category_name}}
            </p>
          </li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

这是一个有效的演示:http://plnkr.co/edit/lgYb8vFsFYpdXqKcMDad?p=preview

答案 1 :(得分:1)

不使用控制器来操纵DOM,最好使用Angular指令 - 它们是为此目的而构建的。

您可以将内容包装在指令中,如下例所示:

app.directive('collection', function () {
    return {
        restrict: "E",
        replace: true,
        scope: {
            collection: '=',
            catTree: '='
        },
        template: '<ul><member full-tree="catTree" cat-tree="catTree[category.level]" ng-repeat="category in collection track by category.category_id" category="category"></member></ul>'
    };
});

app.directive('member', function ($compile) {
    return {
        restrict: "E",
        replace: true,
        scope: {
            member: '=category',
            catTree: '=',
            fullTree: '='
        },
        template: '<li class="ng-hide" ng-show="showItem">{{member.category_name}}</li>',

        link: function (scope, element, attrs) {

            scope.currentTree = {};
            scope.currentTree.category = [];

            scope.showItem = (scope.member.level == '1');

            element.bind('click', function (ev) {
                jQuery(ev.target).siblings('ul').children('li').toggleClass('ng-hide');
                // Prevent Bubble
                return false;
            });

            if (scope.member.has_child_category) {
                for (var cat in scope.catTree) {
                    if (scope.catTree[cat].higher_level_catg_no == scope.member.category_id) {
                        scope.currentTree.category.push(scope.catTree[cat]);
                    }
                }               
                element.append('<collection collection="currentTree.category" cat-tree="fullTree"></collection>');
                $compile(element.contents())(scope);
            }           

        }
    };
});

虽然这些指令目前尚未优化,但它们的目的是演示如何将内容添加到DOM以及如何操作各种项目。

可以在此处测试完整代码:http://plnkr.co/edit/W5K77XlvhcaAoYl0TEpJ?p=preview

您可以在此处找到有关指令的更多信息:http://www.sitepoint.com/practical-guide-angularjs-directives/