使用knockoutjs我想拥有允许无限选择的表单,但我需要显示表单以便用户知道它存在。从3个表单开始我没问题,所以我想在页面渲染时初始化空对象。出于某种原因,当我初始化一个对象时,它会破坏我的代码:
function Task(data) {
this.title=ko.observable(data.title);
this.isDone=ko.observable(data.isDone);
}
function TaskListViewModel() {
// Data
var self=this;
self.tasks=ko.observableArray([]);
// self.tasks.push({'title': ''})
self.newTaskText=ko.observable();
self.incompleteTasks=ko.computed(function() {
return ko.utils.arrayFilter(self.tasks(), function(task) {
return !task.isDone()
});
});
// Operations
self.addTask=function() {
self.tasks.push(new Task({
title: this.newTaskText()
}));
self.newTaskText("");
};
self.removeTask=function(task) {
self.tasks.destroy(task)
};
self.incompleteTasks=ko.computed(function() {
return ko.utils.arrayFilter(self.tasks(),
function(task) {
return !task.isDone() && !task._destroy
});
});
self.save=function() {
$.ajax(".", {
data: ko.toJSON({
tasks: self.tasks
}),
type: "post",
contentType: "application/json",
success: function(result) {
alert(result)
}
});
};
// load initial state from server, convert to tasks, then add em to self.tasks
$.getJSON(".", function(allData) {
var mappedTasks=$.map(allData, function(item) {
return new Task(item)
});
self.tasks(mappedTasks);
});
self.tasks.push({'title': ''})
}
ko.applyBindings(new TaskListViewModel());
body { font-family: Helvetica, Arial }
input:not([type]), input[type=text], input[type=password], select { background-color: #FFFFCC; border: 1px solid gray; padding: 2px; }
.codeRunner ul {list-style-type: none; margin: 1em 0; background-color: #cde; padding: 1em; border-radius: 0.5em;}
.codeRunner ul li a { color: Gray; font-size: 90%; text-decoration: none }
.codeRunner ul li a:hover { text-decoration: underline }
.codeRunner input:not([type]), input[type=text] { width: 30em; }
.codeRunner input[disabled] { text-decoration: line-through; border-color: Silver; background-color: Silver; }
.codeRunner textarea { width: 30em; height: 6em; }
.codeRunner form { margin-top: 1em; margin-bottom: 1em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body class="codeRunner">
<h3> Stuff </h3>
<div data-bind="foreach: tasks, visible: tasks().length > 0">
<p data-bind="value: title"></p>
</div>
<ul data-bind="foreach: tasks, visible: tasks().length > 0">
<li>
<input data-bind="value: title, disable: isDone" />
<a href="#" data-bind="click: $parent.removeTask">Delete</a>
</li>
</ul>
You have <b data-bind="text: incompleteTasks().length"> </b> incomplete task(s)
<span data-bind="visible: incompleteTasks().length == 0"> -it 's beer time!</span>
<form data-bind="submit: addTask"><button type="submit">Add</button></form>
<script>
</script>
</body>
使用这块JS安全地初始化的淘汰模式是什么?谢谢
答案 0 :(得分:1)
您收到错误的原因是您的初始任务中的isDone属性未设置。您还有一个Task viewModel,那么为什么不用它来初始化您的数组呢?我刚刚使用IIFE(立即调用的函数表达式)通过在Task
循环中新增for
来初始化新任务。您可以手动或以您喜欢的方式执行此操作。
另请注意您使用this
关键字。请参阅代码中的self.addTask
。
我不确定这是否正是您正在寻找的,但我认为您需要输入文字输入newTaskText
或我遗失了什么?无论如何,这似乎有效。希望能回答你的问题。
function Task(data) {
this.title = ko.observable(data.title);
this.isDone = ko.observable(data.isDone || false);
}
function TaskListViewModel() {
// Data
var self = this;
self.tasks = ko.observableArray([]);
// self.tasks.push({'title': ''})
self.newTaskText = ko.observable();
self.incompleteTasks = ko.computed(function() {
return ko.utils.arrayFilter(self.tasks(), function(task) {
return !task.isDone()
});
});
// Operations
self.addTask = function() {
self.tasks.push(new Task({
title: self.newTaskText(),
isDone: false
}));
self.newTaskText("");
};
self.removeTask = function(task) {
self.tasks.destroy(task)
};
self.incompleteTasks = ko.computed(function() {
return ko.utils.arrayFilter(self.tasks(),
function(task) {
return !task.isDone() && !task._destroy
});
});
(function(numTasks) {
for (var x = 0; x < numTasks; x++) {
self.tasks.push(new Task({
title: ""
}));
}
})(3)
}
ko.applyBindings(new TaskListViewModel());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body class="codeRunner">
<h3> Stuff </h3>
<input data-bind="textInput: newTaskText" type="text" />
<input data-bind="click: addTask" type="button" value="Add Task" />
<div data-bind="foreach: tasks, visible: tasks().length > 0">
<p data-bind="value: title"></p>
</div>
<ul data-bind="foreach: tasks, visible: tasks().length > 0">
<li>
<input data-bind="value: title, disable: isDone" />
<a href="#" data-bind="click: $parent.removeTask">Delete</a>
</li>
</ul>
You have <b data-bind="text: incompleteTasks().length"> </b> incomplete task(s)
<span data-bind="visible: incompleteTasks().length == 0"> -it 's beer time!</span>
<script>
</script>
</body>
&#13;