Javascript 带有AngularJS的某种俄罗斯娃娃容器的动态编辑表单
问题是 实际上,我必须管理可以包含在db中定义的其他对象的对象。 例如,我有5种盒子。一个红色的盒子,一个绿色的盒子,一个蓝色的盒子,一个黄色的盒子和一个黑色的盒子 每个框可以包含一个框,也可以包含一个框,依此类推 我收到的是这种物品: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":
{
"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>