所以,我不完全确定如何将这个问题说出来,因为它有点二合一。我有一个奇怪的问题,我有一个对象构造函数从HTML表单创建新的'项目',然后在提交表单时将其推送到observableArray。一切正常,但要引用相关的observable,我必须使用'value:Project.title'或'value:Project.whatever'。我还没有看到'value:NameOfConstructor.property'在我见过的任何例子中使用过。我假设这是这样工作的,因为构造函数在我的视图模型之外。
我的问题是:有没有更好的方法在不在我的视图模型中的构造函数中分配属性的值?换句话说,是否有比'Project.title'更好或更正确的方法,等等? 我部分问,因为我的代码中的一件事目前不起作用;敲门启用属性在我的“新建项目”按钮上不起作用,即使在“标题”输入框中写入了某些内容,它也会保持禁用状态。我感觉这是因为它被写成data-bind ='enable:Project.title'但我无法想象如何编写它。
我已经包含了一个jsfiddle供参考,但由于外部依赖性,它显然无效。 https://jsfiddle.net/bmLh0vf1/1/
我的HTML:
<form id='addBox' action='#' method='post'>
<label for='pTitle'> Title: </label>
<input id='pTitle' data-bind='value: Project.title' />
<br/>
<label for='pPriority'> Priority </label>
<select id='pPriority' data-bind='options: priorityOptions, value: Project.priority'></select>
<br/>
<button data-bind='enable: Project.title, click: newProject'>New Project</button>
</form>
我的Javascript:
function Project(title, priority) {
this.title = ko.observable(title);
this.priority = ko.observable(priority);
};
function ProjectViewModel() {
var self = this;
this.priorityOptions = ko.observableArray(['High', 'Medium', 'Low'])
this.projectList = ko.observableArray([
new Project('Create App', 'High')
]);
this.newProject = function() {
var np = new Project(Project.title, Project.priority);
self.projectList.push(new Project(Project.title, Project.priority));
console.log(self.projectList().length);
if (self.projectList().length > 1) {
console.log(self.projectList()[1].title());
};
}
};
var viewModel = new ProjectViewModel();
$(document).ready(function() {
ko.applyBindings(viewModel);
});
最后,如果我错过任何发布约定或者我的代码特别糟糕,我会道歉。我很新,还在教自己。
答案 0 :(得分:2)
您的代码在title
创建的对象上设置了priority
和new Project
属性,但稍后您希望在Project
本身上看到这些属性。它没有它们; Project
是函数,而不是new Project
创建的对象。因此Project.title
和Project.priority
将为您提供undefined
(而不是value
绑定的可观察目标,因此没有用。
相反,有一个&#34;编辑&#34;您使用的Project
实例,将输入的value
绑定到编辑&#39;实例title
和priority
,然后在newProject
中获取该实例并将其替换为新的实例。
粗略地说,在ProjectViewModel
的构造函数中:
this.editing = ko.observable(new Project());
将Project
更新为默认title
和priority
:
function Project(title, priority) {
this.title = ko.observable(title || "");
this.priority = ko.observable(priority || "Medium");
}
在绑定中:
<input id='pTitle' data-bind='value: editing().title' />
<select id='pPriority' data-bind='options: priorityOptions, value: editing().priority'></select>
在newProject
:
var np = this.editing();
this.editing(new Project());
然后在添加到数组时使用np
(而不是另一个new Project
)。
这是一个简单的例子:
function Project(title, priority) {
this.title = ko.observable(title || "");
this.priority = ko.observable(priority || "Medium");
}
function ProjectViewModel() {
var self = this;
this.priorityOptions = ko.observableArray(["High", "Medium", "Low"]);
this.projects = ko.observableArray();
this.editing = ko.observable(new Project());
this.addProject = function() {
this.projects.push(this.editing());
this.editing(new Project());
};
}
ko.applyBindings(new ProjectViewModel(), document.body);
&#13;
<div>
<div>
<label>
Title:
<input type="text" data-bind="value: editing().title, valueUpdate: 'input'">
</label>
</div>
<div>
<label>
Priority:
<select data-bind='options: priorityOptions, value: editing().priority'></select>
</label>
</div>
<div>
<button type="button" data-bind="click: addProject, enable: editing().title">Add Project</button>
</div>
<hr>
<div>Projects:</div>
<div data-bind="foreach: projects">
<div>
<span data-bind="text: title"></span>
(<span data-bind="text: priority"></span>)
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
&#13;