javascript - 如何检查文本框模糊事件的递归数组结构中的重复值?

标签 javascript angularjs

我正在尝试在递归树中为我的节点设置唯一的标题。

因此,当我为我的节点赋予标题时,它应该检查该标题是否已被其他节点使用。如果被采用,它应该提醒用户并且它应该将该节点值重置为以前的值。

任何两个节点都不应具有相同的标题。

但这里的结构是递归的,所以我不知道该怎么做。

注意:我想在文本框失去焦点时立即执行此操作。

var app = angular.module("myApp", []);
        app.controller("TreeController", function ($scope) {
            $scope.delete = function (data) {
                data.nodes = [];
            };
            $scope.add = function (data) {
                var post = data.nodes.length + 1;
                var newName = data.name + '-' + post;
                data.nodes.push({ name: newName, nodes: [],selected : false, myObj: { name: newName} });
            };
            $scope.tree = [{ name: "Node", nodes: [], selected: false }];

            $scope.setActive = function ($event, data) {
            	$event.stopPropagation();
                $scope.selectedData = data;
                clearDivSelection($scope.tree);
                data.selected = true;
            };

            function clearDivSelection(items) {
                items.forEach(function (item) {
                    item.selected = false;
                    if (item.nodes) {
                        clearDivSelection(item.nodes);
                    }
                });
            }
            
            $scope.checkDuplicateNodeName = function () {
             alert()
            }
        });
ul {
    list-style: circle;
}
li {
    margin-left: 20px;
}
 .active { background-color: #ccffcc;}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>


<ul ng-app="myApp" ng-controller="TreeController">
        <li ng-repeat="data in tree" ng-include="'tree_item_renderer.html'"></li>
        <script type="text/ng-template" id="tree_item_renderer.html">
            <div ng-class="{'active': data.selected}" > {{data.myObj.name}}</div>
            <button ng-click="add(data)">Add node</button>
            <button ng-click="delete(data)" ng-show="data.nodes.length > 0">Delete nodes</button>
            <ul>
                <li ng-repeat="data in data.nodes" ng-include="'tree_item_renderer.html'" ng-click="setActive($event, data)"></li>
            </ul>
        </script>
        <div style="margin-left:100px;">
           Title :  <input type="text" ng-model="selectedData.myObj.name" ng-blur="checkDuplicateNodeName()" />
           Location :  <input type="text" ng-model="selectedData.myObj.location" />

        </div>
    </ul>

最佳答案

我的解决方案

  1. 在 blur 上存储经过验证的名称副本(意味着有 3 个名称,但我不知道 myObj.name 的意义,所以我将其保留原样,您可以清理)
  2. 以递归方式查找重复项,在第一个 true 处停止。如果存在欺骗,则使用最后一个有效名称,否则更新最后一个有效名称。

为什么

  1. 您只想在 blur 上验证名称。 angular 提供了验证 ng-model 的方法在每次更改时,解析器和格式化程序都将完全限制用户保留一个欺骗名称。有很多方法可以解决这个问题(验证器、无需持久化的编辑),并且都需要不同类型的解决方案。探索并选择最适合您的方法
  2. 使用 hashMap(我的第一个想法)将需要对重命名和删除进行清理逻辑,这最终会使代码进一步复杂化

如果您希望仅在节点的树中搜索重复项,您需要存储对父节点的引用,并使用 getTree 方法来确定要搜索的根节点。

var app = angular.module("myApp", []);
app.controller("TreeController", function($scope) {
  $scope.delete = deleteNodes;
  $scope.add = add;
  $scope.setActive = setActive;
  $scope.checkDuplicateNodeName = checkDuplicateNodeName;
  $scope.trees = [{
    name: "Node",
    nodes: [],
    selected: false
  },{
    name: "Node2",
    nodes: [],
    selected: false
  }];

  function deleteNodes(data) {
    data.nodes = [];
  }

  function add(data) {
    var post = data.nodes.length + 1;
    var newName = data.name + '-' + post;
    
    data.nodes.push({
      name: newName,
      nodes: [],
      selected: false,
      validatedName: newName
    });
  }

  function setActive($event, data) {
    $event.stopPropagation();
    if($scope.selectedData) {
      $scope.selectedData.selected = false;
    }
    $scope.selectedData = data;
    
    data.selected = true;
  }

  function checkDuplicateNodeName() {
    if(!$scope.selectedData)
      return;
  
    var dupe = false;
    
    for(var idx = 0; idx < $scope.trees.length; idx++) {
      if(isDuplicateName($scope.trees[idx], $scope.selectedData)) {
        dupe = true;
        break;
      }
    }
    
    if(dupe){
      alert('The name "' + $scope.selectedData.name + '" already exists');
      $scope.selectedData.name = $scope.selectedData.validatedName;
    } else {
      $scope.selectedData.validatedName = $scope.selectedData.name;
    }

  }
  
  function getTree(node){
    while(node.parent) {
      node = node.parent;
    }
    
    return node;
  }
  
  function isDuplicateName(node, nodeToCheck) {
    var dupeName = node != nodeToCheck && node.name && nodeToCheck.name && node.name == nodeToCheck.name;
    if(dupeName) return true;
    
    if(node.nodes){
      for(var idx=0; idx< node.nodes.length; idx++) {
        if(isDuplicateName(node.nodes[idx], nodeToCheck)){
          return true;
        }
      }
    }
    return false;
  }
});
ul {
  list-style: circle;
}

li {
  margin-left: 20px;
}

.active {
  background-color: #ccffcc;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>


<ul ng-app="myApp" ng-controller="TreeController">
  <li ng-repeat="data in trees" ng-include="'tree_item_renderer.html'"></li>
  <script type="text/ng-template" id="tree_item_renderer.html">
    <div ng-class="{'active': data.selected}"> {{data.name}}</div>
    <button ng-click="add(data)">Add node</button>
    <button ng-click="delete(data)" ng-show="data.nodes.length > 0">Delete nodes</button>
    <ul>
      <li ng-repeat="data in data.nodes" ng-include="'tree_item_renderer.html'" ng-click="setActive($event, data)"></li>
    </ul>
  </script>
  <div style="margin-left:100px;">
    Title : <input type="text" ng-model="selectedData.name" ng-blur="checkDuplicateNodeName()" /> Location : <input type="text" ng-model="selectedData.myObj.location" />

  </div>
</ul>

关于javascript - 如何检查文本框模糊事件的递归数组结构中的重复值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44070130/

相关文章:

javascript - 多个无限循环

angularjs - 在 Angular 中使用 lb-services 计数服务

javascript - 获取元素的值

javascript - IndexedDB 事务和 Promises 之间的相互作用不一致

javascript - Underscore.js 的 map 函数正在就地改变 DOM 元素数组并返回 'undefined' 为什么?

angularjs - Angular 分组依据和过滤器

Angularjs ng-grid REST 调用

javascript - 动态变量到 angularjs ng-repeat

javascript - 数据绑定(bind)在 AngularJS 中是如何工作的?

javascript - 如何更改输入元素的值?