Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript angularjs中动态嵌套表单模型上的绑定数据_Javascript_Angularjs_Model View Controller - Fatal编程技术网

Javascript angularjs中动态嵌套表单模型上的绑定数据

Javascript angularjs中动态嵌套表单模型上的绑定数据,javascript,angularjs,model-view-controller,Javascript,Angularjs,Model View Controller,我从json对象(比如formObject)生成嵌套表单,并绑定json对象本身中的值。我递归地解析这些值,并在提交时提取实际数据,比如dataObject 我可以像这样以线性形式检索数据对象 这是一个解决方案&我可以在提交时获得,$scope.firstfiddle的答案(我认为)不允许这种嵌套。但是当我必须更新现有的数据对象时,我觉得有必要在呈现它之前将数据对象映射到formObject,然后在提交时再次解析。 现在这不是MVC,看起来不优雅(由于递归)&我认为这有一种“角度的方式” 有没有

我从json对象(比如formObject)生成嵌套表单,并绑定json对象本身中的值。我递归地解析这些值,并在提交时提取实际数据,比如dataObject

我可以像这样以线性形式检索数据对象

这是一个解决方案&我可以在提交时获得,$scope.firstfiddle的答案(我认为)不允许这种嵌套。但是当我必须更新现有的数据对象时,我觉得有必要在呈现它之前将数据对象映射到formObject,然后在提交时再次解析。 现在这不是MVC,看起来不优雅(由于递归)&我认为这有一种“角度的方式”


有没有人尝试过这一点&让它以更好的方式工作?我该如何解决这个问题呢?

不是很好,但这是您已经提出的解决方案的替代方案

功能控制器($scope){
$scope.answers={};
$scope.tempOption=“”;
$scope.questions=[
{
“文本”:“性别?”,
“姓名”:“性别问题”,
“选项”:[“男性”、“女性”]},
{
“文本”:“最喜欢的颜色?”,
“名称”:“颜色问题”,
“选项”:[“红色”、“蓝色”、“绿色”]}
];
$scope.showAnswers=函数(){
log($scope.answers);
};
$scope.pumpOption=函数(名称,临时选项){
$scope.answers[name]=tempOption;
};
};
  • {{问题.文本}
我们将select标记中所选选项的值绑定到$scope.tempOption变量

然后,我们监听在这个select标记上发生的ng change事件,在这里我们运行一个函数,该函数使用$scope.tempOption变量加上与select标记关联的{question.name}

然后,此函数将answers[name]设置为当前值$scope.tempOption


希望这对你有用,祝你好运:)

只需创建
$scope.Answer={}并将ng模型链接到它

好的-这并不像我第一次想的那么简单,所以我希望这就是你想要的-你需要使用一个指令来动态生成它的模板HTML(更好的是,使用templateUrl和一个传入类型的函数)

TLDR:看到小提琴了吗

HTML非常简单

<div ng-controller="questionsController">

<!-- for each question, render section or question -->
<div ng-repeat="item in Questions">
    <!-- we ignore section here as it's a root section -->
    <question item="item"></question>
</div>

您需要创建一个指令来呈现问题和部分。它还需要跟踪该部分,以便构建答案

.directive('question', ['$compile', '$templateCache', function ($compile, $templateCache) {
    var generateHtmlTemplate = function (item, section) {
        return item.type != 'section' ?
        // render the question    
        'question ' + item.name + '<br/>' +
            '<select ng-model="optionValue" ng-options="opt for opt in item.options" ng-change="pushAnswer(item.name, section, optionValue)"></select>' :
        // or the template for a section
        '<br/><hr/>section ' + item.sectionName + '<br/>' +
            '<div ng-repeat="q in item.questions"><question item="q" section="item"></question></div><hr/>';
    }

    var currentSection = null;

    return {
        scope: {
            item: '=',
            section: '='
        },
        restrict: 'E',
        link: function ($scope, element, attrs) {
            // check current section
            if ($scope.item.type == 'section') {
                // set new current section
                $scope.currentSection = $scope.item;
            } else {
                // use section passed in from parent section
                $scope.currentSection = $scope.section;
            }

            // get template html
            var t = generateHtmlTemplate($scope.item, $scope.currentSection);

            // set the scope function to set the value
            $scope.pushAnswer = function (q, section, value) {
                // build the Answers object here however you want...
                if (section != null) {
                    console.log('pushAnswer q=' + q.name + ' - section=' + section.sectionName + ' - value=' + value);
                } else {
                    console.log('pushAnswer q=' + q.name + ' - section=rootSection - value=' + value);
                }

            };

            // chuck it into element as template
            element.html(t);

            // compile it up and return it
            $compile(element.contents())($scope);
        },
    };
}])
.directive('question',['$compile','$templateCache',函数($compile,$templateCache){
var generateHtmlTemplate=函数(项,节){
return item.type!=“section”?
//提出问题
“问题”+item.name+“
”+ '' : //或节的模板 “

section”+item.sectionName+”
”+ “
”; } var currentSection=null; 返回{ 范围:{ 项目:'=', 节:'=' }, 限制:'E', 链接:函数($scope,element,attrs){ //检查当前部分 如果($scope.item.type=='section'){ //设置新的当前节 $scope.currentSection=$scope.item; }否则{ //使用从父节传入的节 $scope.currentSection=$scope.section; } //获取模板html var t=generateHtmlTemplate($scope.item,$scope.currentSection); //设置范围函数以设置值 $scope.pushAnswer=函数(q、节、值){ //在此处创建您想要的答案对象。。。 if(节!=null){ log('pushAnswer q='+q.name+'-section='+section.sectionName+'-value='+value)); }否则{ log('pushAnswer q='+q.name+'-section=rootSection-value='+value); } }; //将其作为模板放入元素中 html(t); //编译并返回它 $compile(element.contents())($scope); }, }; }])
好吧,我是开玩笑的。 但是,您是否尝试过使用与平面相关的对象关系表方法而不是嵌套的方法

{
  sections:[
    { "Name": 'Personal', "questions":[0], sub:[1] },
    { "Name": 'SubPersonal', "questions":[3], sub:[]},
    { "Name": 'Random',   "questions":[1,2], sub:[] }
  ],
  questions:[
    { "Name":"Gender",     "Text":"Gender?",         "Options":["Male", "Female"] },
    { "Name":"Color",      "Text":"Favorite Color?", "Options":["Red","Blue","Green"] },
    { "Name":"LivingWith", "Text":"Living With?",    "Options":["Alone","Someone"] },
    { "Name":"Random",     "Text":"SectionLess",     "Options":["opt1", "opt2"] }
  ]
}

是的,这是可行的,但是当我有嵌套对象的json数据时,递归下的情况看起来很糟糕。我现在有,但它不是MVC&通过相同的表单更新字段还有一些工作要做。我不太理解你的方法的问题。可能是因为JSFIDLE上的示例不够复杂-没有提到“递归”和“提交时再次解析”的需要-
$scope。由于Angular的数据绑定,答案总是最新的,随时可以提交。但可能是因为我太困了:)不管怎样,如果你能把小提琴做得更精细一些(但不要太夸张,要欣赏hello worldish风格),以充分说明你当前方法的缺点,那就太酷了。正如@vucalur所说,我也不太明白小提琴有什么问题。我在示例中也没有看到任何递归。你能更新你的问题并更好地解释你的问题是什么吗?是的,试着解释一下!很抱歉第一次没有详细阐述问题陈述,我对简洁有一些奇怪的想法@vucalur,现在问题清楚了吗?或者我还需要进一步阐述吗?是的,这是一种方法,但它仍然不能解决筑巢的问题。例如,我不能使用
答案[0]。值[0]。GenderQuestion
而不引用它的元素
答案[0]。值[0]
。是的,但是我必须写一些东西来生成原始对象。我不想在平面表中表示我的数据模型!H
<div ng-controller="questionsController">

<!-- for each question, render section or question -->
<div ng-repeat="item in Questions">
    <!-- we ignore section here as it's a root section -->
    <question item="item"></question>
</div>
.directive('question', ['$compile', '$templateCache', function ($compile, $templateCache) {
    var generateHtmlTemplate = function (item, section) {
        return item.type != 'section' ?
        // render the question    
        'question ' + item.name + '<br/>' +
            '<select ng-model="optionValue" ng-options="opt for opt in item.options" ng-change="pushAnswer(item.name, section, optionValue)"></select>' :
        // or the template for a section
        '<br/><hr/>section ' + item.sectionName + '<br/>' +
            '<div ng-repeat="q in item.questions"><question item="q" section="item"></question></div><hr/>';
    }

    var currentSection = null;

    return {
        scope: {
            item: '=',
            section: '='
        },
        restrict: 'E',
        link: function ($scope, element, attrs) {
            // check current section
            if ($scope.item.type == 'section') {
                // set new current section
                $scope.currentSection = $scope.item;
            } else {
                // use section passed in from parent section
                $scope.currentSection = $scope.section;
            }

            // get template html
            var t = generateHtmlTemplate($scope.item, $scope.currentSection);

            // set the scope function to set the value
            $scope.pushAnswer = function (q, section, value) {
                // build the Answers object here however you want...
                if (section != null) {
                    console.log('pushAnswer q=' + q.name + ' - section=' + section.sectionName + ' - value=' + value);
                } else {
                    console.log('pushAnswer q=' + q.name + ' - section=rootSection - value=' + value);
                }

            };

            // chuck it into element as template
            element.html(t);

            // compile it up and return it
            $compile(element.contents())($scope);
        },
    };
}])
var model = {
    colors:["Red","Blue","Green","Black","White"],
    genders:["Male", "Female"],
    topic:["Gender", "Color"],
    category:["Favorite", "Least favorite"],
};

function makeQuestion(topic, category){
    return (category+1 ? model.category[category] + ' ' : '') 
    + ' ' + model.topic[topic] + '?'
}

function QuestionController($scope){

    $scope.Answers = {};
    $scope.Questions = [
        {
            "Text": makeQuestion(0),
            "Name": "GenderQuestion",
            "Options": model.genders 
        },{
            "Text": makeQuestion(1,0),
            "Name": "ColorQuestion",
            "Options": model.colors.slice(0,3)
        },{
            "Text": makeQuestion(0,1),
            "Name": "SexistQuestion",
            "Options": model.genders
        },{
            "Text": makeQuestion(1,1),
            "Name": "RacistQuestion",
            "Options":model.colors.slice(3)
        }
    ];

    $scope.ShowAnswers = function()
    {
        console.log($scope.Answers);
    };
}    
{
  sections:[
    { "Name": 'Personal', "questions":[0], sub:[1] },
    { "Name": 'SubPersonal', "questions":[3], sub:[]},
    { "Name": 'Random',   "questions":[1,2], sub:[] }
  ],
  questions:[
    { "Name":"Gender",     "Text":"Gender?",         "Options":["Male", "Female"] },
    { "Name":"Color",      "Text":"Favorite Color?", "Options":["Red","Blue","Green"] },
    { "Name":"LivingWith", "Text":"Living With?",    "Options":["Alone","Someone"] },
    { "Name":"Random",     "Text":"SectionLess",     "Options":["opt1", "opt2"] }
  ]
}