Javascript 带有AngularJS的某种俄罗斯娃娃容器的动态编辑表单

Javascript 带有AngularJS的某种俄罗斯娃娃容器的动态编辑表单,javascript,html,css,angularjs,loops,Javascript,Html,Css,Angularjs,Loops,问题是 实际上,我必须管理可以包含在db中定义的其他对象的对象。 例如,我有5种盒子。一个红色的盒子,一个绿色的盒子,一个蓝色的盒子,一个黄色的盒子和一个黑色的盒子 每个框可以包含一个框,也可以包含一个框,依此类推 我收到的是这种物品: { "id":1, "type":"black", "box": { "id":8, "type":"red", "box": { "id":

问题是

实际上,我必须管理可以包含在db中定义的其他对象的对象。 例如,我有5种盒子。一个红色的盒子,一个绿色的盒子,一个蓝色的盒子,一个黄色的盒子和一个黑色的盒子

每个框可以包含一个框,也可以包含一个框,依此类推

我收到的是这种物品:

{
    "id":1,
    "type":"black",
    "box":
    {
        "id":8,
        "type":"red",
        "box":
        {
            "id":15,
            "type":"green",
            "box":null
        }
    }
}
所以这个例子是:一个黑盒子,包含一个红盒子,包含一个空的绿盒子。(黑色->红色->绿色->空)

有以下条件:

  • 黑框只能包含蓝色、绿色和红色
  • 红色框只能包含绿色和黄色
  • 黄色的盒子里什么都不能装
  • 其他框(绿色和蓝色)可以包含任何内容
我需要做的是某种“框集编辑器”,我收到一个框对象,它是否复杂(这意味着它只能有一个或多个框级别)。我必须在选择框列表中表示它,因此,对于我编写的示例,它将显示以下内容:


没有一个
黑色
红色
绿色
蓝色
黄色的

没有一个 红色 绿色 蓝色
没有一个 绿色 黄色的
没有一个 绿色 红色 蓝色 黄色的 黑色
试试这个例子:

使用checkInnerObject函数,它将返回“框”的计数,请参见示例

更新:



Eample:

您的问题很长,如果我下面的回答不符合您的所有条件,请原谅。说到这里,我想如果你不必创造这种东西(俄罗斯娃娃),那么我们就不必太担心了

这样做:-

var reallyLengthyBoxObj = {
"id":"1",
"type":"black",
"box":{
    "id":"8",
    "type":"red",
    "box":{
        "id":"15",
        "type":"green",
        "box":{
            "id":"15",
            "type":"green",
            "box":{
                "id":"15",
                "type":"green",
                "box":null
            }
        }
    }
}
}

$scope.boxObjArr = [],
    $scope.selectedBoxes = {};
    i = 0;
function recurseMe(boxObj){
   i++;
   $scope.selectedBoxes["level"+i] = null;
   var  obj = {};
   obj.id = boxObj.id;
   obj.type = boxObj.type;
   obj.level = i;
   try{
      var haskeys = Object.keys(boxObj.box);
      obj.isParent = true;
      $scope.boxObjArr.push(obj);
      recurseMe(boxObj.box);
   }catch(e){
      obj.isParent = false;
      $scope.boxObjArr.push(obj);
      return;
   }
}

recurseMe(reallyLengthyBoxObj);
这样,您将获得一个包含所有框及其级别的数组。现在我假设重复的ID不会(也不应该)从您的服务器中出现。否则,我们的逻辑就会增长

现在您已经准备好了两件事-
$scope.boxObjArr
$scope.selectedbox

用html编写:

<div ng-repeat="(key,value) in selectedBoxes">
   <select ng-model="value" ng-if="key=='level1' || selectedBoxes[key.slice(0,key.length-1)+(key.slice(-1)-1)] != null">
     <option ng-repeat="box in boxObjArr" ng-show="key=="level1" || box.level < selectedBoxes[key.slice(0,key.length-1)+(key.slice(-1)-1)].level">
     </option>
   </select>
</div>

javascript部分已经完成并正常工作。不确定我是否在HTML部分犯了错误。但我认为您已经了解了如何以及为什么要形成
$scope.selectedbox
$scope.boxObjArr

希望它能以最短的方式解决您的问题


谢谢

基于您的JSFIDLE代码,我想我已经按照您想要的方式工作了:

var-app=angular.module('myApp',[]);
app.controller('BoxController',['$scope','BoxService',函数($scope,BoxService){
$scope.currentBox={};
$scope.currentSelection=[];
$scope.currentOptions=[];
$scope.defaultOptions=[{
“id”:1,
“类型”:“黑色”
}, {
“id”:8,
“类型”:“红色”
}, {
“id”:15,
“类型”:“绿色”
}, {
“id”:10,
“类型”:“黄色”
}, {
“id”:3,
“类型”:“蓝色”
}];
//此对象将每个框的ID映射到其长度。例如,
//`BoxLength['1']=2`表示ID为'1'的框包含2个框。
$scope.boxLength={};
$scope.setCurrentBox=函数(id){
getBoxItem(id,函数(框){
$scope.currentBox=box;
//将长方体从树结构转换为平面数组`数据`
getBoxesAsTab(框,函数(数据){
$scope.currentSelection=数据;
$scope.currentOptions=[];
//我们现在知道当前框包含'data.length-1'框
//(减去1,因此我们不计算'data'数组中的第一个框)
$scope.boxLength[id]=data.length-1;
角度.forEach(数据、函数(项、索引){
getBoxOptions(项目类型、功能(选项){
$scope.currentOptions[索引]=选项;
});
});
});
});
};
//每当``框更改值时,就会调用它
$scope.updateSelection=函数(索引,choiceId){
//将数组向下截断到指定索引处的元素`
// http://stackoverflow.com/a/6928247/5249519
$scope.currentSelection.length=索引+1;
$scope.currentOptions.length=索引+1;
//如果用户选择“NO CHOICE”,则`choiceId`将为`null`
如果(choiceId==null){
//更新当前框包含的框数
//(减去1,因此我们不计算数组中的第一个框)。
//注意:如果用户选择“无选择”作为第一个选择,
//此时,“$scope.currentBox.id”将为null,
//但我不知道你在这种情况下想做什么。。。
$scope.boxLength[$scope.currentBox.id]=$scope.currentSelection.length-1;
//更新链中相应的对象引用
如果(索引==-1){
$scope.currentBox=null;
}否则{
$scope.currentSelection[index].box=null;
}
//在这里停下来,然后回来
返回;
}
//否则,创建链中的下一个项目
变量nextItem={
id:choiceId,
类型:“”,
框:空
};
//给定'id',在'defaultOptions'数组中找到相应的'type'名称
对于(变量i=0;i<$scope.defaultOptions.length;i++){
if($scope.defaultOptions[i].id==nextItem.id){
nextItem.type=$scope.defaultOptions[i].type;
打破
}
}
//更新链中相应的对象引用
如果(索引==-1){
$scope.currentBox=nextItem;
}否则{
$scope.currentSelection[index].box=nextItem;
}
//将'nextItem'添加到'currentSelection'数组中
$scope.currentSelection.push(nextItem);
//获取'nextItem'的选项并将其添加到'currentOptions'数组中
getBoxOptions(nextItem.type,函数(选项){
$scope.currentOptions.push(选项);
});
<div ng-repeat="(key,value) in selectedBoxes">
   <select ng-model="value" ng-if="key=='level1' || selectedBoxes[key.slice(0,key.length-1)+(key.slice(-1)-1)] != null">
     <option ng-repeat="box in boxObjArr" ng-show="key=="level1" || box.level < selectedBoxes[key.slice(0,key.length-1)+(key.slice(-1)-1)].level">
     </option>
   </select>
</div>