毫无疑问,我在这里遗漏了一些明显的东西。这是我创建的第一个前端应用程序。
I'd like to have a client side select box which when an option is chosen, a separate property on the entity will be updated. 含义当更改选择框时,调用一个函数,然后将适当地更新其他属性。我遇到的问题是,在客户端创建实体时,选择框不会呈现。
在图片中:
第一步:页面加载完毕。实体存在,没有孩子:
第二步:点击Add Child,创建一个子实体。如您所见,选择框没有选项。使用 Chrome Knockout 插件,我可以看到包含应该呈现的选项的属性是正确的。
第三步:我点击保存,然后刷新页面。选择框正确呈现,但重要的是填充此选择框的值与第二步相同(通过敲除 chrome 插件验证)。
HTML:
<section data-bind="with: parent">
<div data-bind="foreach: children">
<select name="propertyOne"
data-bind="options: propertyOneOptions, value: propertyOne, optionsText: 'description', optionsCaption: 'Select a Property'">
</select>
<br />
</div>
<button data-bind="click: $root.addChild">Add Child</button>
</section>
<button data-bind="click: save">Save</button>
查看型号:
如您所见,在 initVm 方法和 addChild 方法中,我都在填充 child.propertyOneOptions。
app.viewModel = (function (logger, dataservice) {
var parent = ko.observable(null);
var propertyOneValues = ko.observableArray([]);
var vm = {
addChild: addChild,
parent: parent,
save: save,
};
initVm();
return vm;
function initVm() {
propertyOneValues.push({
key: 'key 1',
description: 'value 1'
});
propertyOneValues.push({
key: 'key 2',
description: 'value 2'
});
dataservice.getAllParents()
.then(function (data) {
console.log('Number of parents = ' + data.results.length);
if (data.results.length > 0) {
parent(data.results[0]);
} else {
parent(dataservice.createParent());
dataservice.saveChanges().fail(queryFailed);
}
ko.utils.arrayForEach(parent().children(), function (child) {
console.log('Populating Child ' + child.propertyOneOptions().length);
ko.utils.arrayForEach(propertyOneValues(), function (value) {
child.propertyOneOptions.push(value);
});
console.log('Populated Child ' + child.propertyOneOptions().length);
});
}).fail(queryFailed);
}
function queryFailed(error) {
console.log('Query failed: ' + error.message);
}
function save() {
dataservice.saveChanges().fail(queryFailed);
}
function addChild() {
var child = dataservice.createChild(parent);
console.log('Creating Child ' + child.propertyOneOptions().length);
ko.utils.arrayForEach(propertyOneValues(), function (value) {
child.propertyOneOptions.push(value);
});
console.log('Populated Child ' + child.propertyOneOptions().length);
}
})(app.logger, app.dataservice);
// Bind viewModel to view in index.html
ko.applyBindings(app.viewModel);
子初始化器:
propertyOne 和 propertyOneOptions 正在创建一个轻而易举的实体初始化器:
function childInitializer(child) {
child.propertyOne = ko.observable();
child.propertyOneOptions = ko.observableArray();
}
数据模型:
public class Parent
{
public Parent()
{
Children = new List<Child>();
}
[Key]
public int Id { get; set; }
public String OtherProperty { get; set; }
public IList<Child> Children { get; set; }
}
public class Child
{
[Key]
public int Id { get; set; }
public int ParentId { get; set; }
[ForeignKey("ParentId")]
public Parent Parent { get; set; }
}
更新 1
在阅读了这篇关于性能的文章后,我补充道:
parent().children.valueHasMutated();
到 addChild 方法和事情的末尾有所改进,即子选择框确实渲染,但正确子下面有一个幻像子:更新了第二步