Knockout.js 杂项对象的剔除数组

Knockout.js 杂项对象的剔除数组,knockout.js,Knockout.js,我正在使用Knockout编写一个基本调查应用程序的演示。我需要在我的调查中包括两类问题,用户可以根据自己的意愿添加它们。例如,他们可能希望在调查中添加一个基本问题,然后再添加一个选择题。基本问题将由文本标签(用于问题)和文本字段(用于最终用户输入)组成。选择题由一行或多行组成,每行包含一个文本标签和一个复选框 我写了一些击倒: -生成基本问题列表 -生成多项选择题的选择选项列表 我现在需要的是将这两种类型的问题存储在一个数组中,所以我猜数组对象需要是调查问题的一个更通用的版本-一个可以是基本文

我正在使用Knockout编写一个基本调查应用程序的演示。我需要在我的调查中包括两类问题,用户可以根据自己的意愿添加它们。例如,他们可能希望在调查中添加一个基本问题,然后再添加一个选择题。基本问题将由文本标签(用于问题)和文本字段(用于最终用户输入)组成。选择题由一行或多行组成,每行包含一个文本标签和一个复选框

我写了一些击倒: -生成基本问题列表 -生成多项选择题的选择选项列表

我现在需要的是将这两种类型的问题存储在一个数组中,所以我猜数组对象需要是调查问题的一个更通用的版本-一个可以是基本文本问题或多项选择问题,本身就是一个选择选项数组

我曾想过使用一个包含所有类型问题的所有元素的通用问题对象,但这会带来很大的开销,因为每个简单的文本问题还需要包含一系列选择选项,如果我添加其他类型的问题,情况只会变得更糟

有人能提出最好(或最简洁)的前进方向吗

感谢您的关注:)

好的,我添加了以下内容作为我的JavaScript:

var SurveyModel = function () {
    var self = this;
    self.questions = ko.observableArray([]);
    self.addQuestion = function (item) {
        self.questions.push( item );
    };
    self.addQuestion("{ name: 'basic-question-template' }");
    self.addQuestion("{ name: 'checkbox-question-template' }");
    self.addQuestion("{ name: 'checkbox-question-template' }");
};

window.jQuery(function () {
    var viewModel = new SurveyModel();
    ko.applyBindings(viewModel);
});
…我的标记如下所示:

<script type="text/html" id="basic-question-template">
    <table>
        <tr>
            <td>Please enter a question:</td>
            <td><input data-bind="value: txtQuestion" /></td>
        </tr>
        <tr>
            <td>Please enter a hint:</td>
            <td><input data-bind="value: txtResponse" /></td>
        </tr>
    </table>
</script>

<script type="text/html" id="checkbox-question-template">
    <table>
        <tr>
            <td>Please enter a question:</td>
            <td><input data-bind="value: txtQuestion" /></td>
        </tr>
        <tr>
            <td>Please enter a hint:</td>
            <td><input type="checkbox" value="cbValue" data-bind="checked: false" /></td>
        </tr>
    </table>
</script>

<div id="frmSurvey" class="">
    <h2>Questions</h2>
    <div data-bind='template: { name: scriptID, foreach: questions }'> </div>
</div>
</code>
function MainViewModel() {
  var self = this;
  this.questions = ko.observableArray();
}

function QuestionViewModel(type)
{
  var self = this;
  this.type = type;
  this.textQuestion = ko.observable();
  this.options = ko.observableArray();
  this.addOption = function() { self.options.push(new OptionValueViewModel()); }
}

function OptionValueViewModel() 
{
  this.text = ko.observable();
  this.checked = ko.observable(false);
}

请输入一个问题:
请输入提示:
请输入一个问题:
请输入提示:
问题

我不知道为什么会增加开销,或者我不理解你的问题。如果您使用类似以下内容:

<script type="text/html" id="basic-question-template">
    <table>
        <tr>
            <td>Please enter a question:</td>
            <td><input data-bind="value: txtQuestion" /></td>
        </tr>
        <tr>
            <td>Please enter a hint:</td>
            <td><input data-bind="value: txtResponse" /></td>
        </tr>
    </table>
</script>

<script type="text/html" id="checkbox-question-template">
    <table>
        <tr>
            <td>Please enter a question:</td>
            <td><input data-bind="value: txtQuestion" /></td>
        </tr>
        <tr>
            <td>Please enter a hint:</td>
            <td><input type="checkbox" value="cbValue" data-bind="checked: false" /></td>
        </tr>
    </table>
</script>

<div id="frmSurvey" class="">
    <h2>Questions</h2>
    <div data-bind='template: { name: scriptID, foreach: questions }'> </div>
</div>
</code>
function MainViewModel() {
  var self = this;
  this.questions = ko.observableArray();
}

function QuestionViewModel(type)
{
  var self = this;
  this.type = type;
  this.textQuestion = ko.observable();
  this.options = ko.observableArray();
  this.addOption = function() { self.options.push(new OptionValueViewModel()); }
}

function OptionValueViewModel() 
{
  this.text = ko.observable();
  this.checked = ko.observable(false);
}
您可以创建新的QuestionViewModel,传递类型字符串(“文本”或“选择”或对您有意义的内容),然后根据类型,UI可以绘制一个或其他类型的问题

如果为某个问题添加了选项,则不会将该数组添加到其他问题,因为每个问题都独立于viewModel.questions数组


如果不是。。。我真的不明白这个问题。

没有理由让obserableArray中的对象必须是同一类型的

我想推荐如下:

<script type="text/html" id="basic-question-template">
    <table>
        <tr>
            <td>Please enter a question:</td>
            <td><input data-bind="value: txtQuestion" /></td>
        </tr>
        <tr>
            <td>Please enter a hint:</td>
            <td><input data-bind="value: txtResponse" /></td>
        </tr>
    </table>
</script>

<script type="text/html" id="checkbox-question-template">
    <table>
        <tr>
            <td>Please enter a question:</td>
            <td><input data-bind="value: txtQuestion" /></td>
        </tr>
        <tr>
            <td>Please enter a hint:</td>
            <td><input type="checkbox" value="cbValue" data-bind="checked: false" /></td>
        </tr>
    </table>
</script>

<div id="frmSurvey" class="">
    <h2>Questions</h2>
    <div data-bind='template: { name: scriptID, foreach: questions }'> </div>
</div>
</code>
function MainViewModel() {
  var self = this;
  this.questions = ko.observableArray();
}

function QuestionViewModel(type)
{
  var self = this;
  this.type = type;
  this.textQuestion = ko.observable();
  this.options = ko.observableArray();
  this.addOption = function() { self.options.push(new OptionValueViewModel()); }
}

function OptionValueViewModel() 
{
  this.text = ko.observable();
  this.checked = ko.observable(false);
}
  • 为每个问题类型的显示模式创建脚本HTML模板
  • 为所有问题共有的属性创建BaseQuestionModel类,但至少有一个标识符属性和一个存储要调用的显示模板的属性
  • 例如,您还可以有一个编辑模板,这样多项选择题的编辑方式就可以不同于自由格式文本题等
  • 使用BaseQuestionModel从BaseQuestionModel创建子类。为每个问题类型应用(此参数),显式设置显示模板属性
  • 将这些子类的实例推送到observableArray
  • 根据问题的显示模板,使用模板绑定适当地显示问题
更新:

所以。。。你对你的新代码有点熟悉,但不是很熟悉

您只是将字符串推送到问题数组,而不是实际对象。所以你想要的是:

var CheckboxQuestion = function() {
var self = this;
self.scriptID = ko.observable('checkbox-question-template');
self.txtQuestion = ko.observable();
self.checked = ko.observable();
}

var BasicQuestion = function() {
var self = this;
self.scriptID = ko.observable('basic-question-template');
self.txtQuestion = ko.observable();
self.txtResponse = ko.observable();
}

var SurveyModel = function () {
var self = this;
self.questions = ko.observableArray([]);
self.addQuestion = function (item) {
self.questions.push( item );
};

bq1 = new BasicQuestion();
bq1.txtQuestion('What is your name?');
bq1.txtResponse('Hint goes here');

self.addQuestion( bq1 );

cbq1 = new CheckboxQuestion();
cbq1.txtQuestion('Are you a zombie?');

self.addQuestion(cbq1);

};

现在,当您的视图浏览
问题的每个成员时,它将找到模板的
scriptID
值,然后每个模板将获取项目并将可观察值应用到模板。

感谢您的回复;我根据您的建议找到了模板绑定文档,看起来这就是未来的方向。不幸的是,我没有取得多大的进步,因为我上一次看KO是在一年多以前。根据您的回复,我创建了两个脚本,一个用于带有文本框回复的问题,另一个带有复选框。我想我需要创建每个问题的一个实例,然后将它们添加到我的基本问题数组中,并使用如下方式呈现后者:好吧,我编辑了我的原始问题,以显示我是如何尝试这样做的,但我仍然缺少一些东西。有什么想法吗?快速更改我的标记,效果很好-谢谢,祝你周末愉快!:)