我有一个由project
对象,text
对象和setting
对象组成的模型。 settings
对象可以包含projects
和texts
的值。
text
始终与project
相关联。因此,它应该继承project
s settings
(如果有的话)。但是,如果text
本身具有settings
,则用户应该能够在使用项目默认值或特定于文本的settings
之间进行选择。
我在项目中遇到的问题是更新文本本地设置也会更新项目默认设置。我想这与observables关系有关,但到目前为止我一直无法找到连接。
这是我的代码:
Text = function (data) {
var self = this;
self.textID = data.textID;
self.title = ko.observable(data.title);
self.projectID = data.projectID;
// settings
self.settings = ko.observable(); // initiated with "each" loop hook-up in viewmodel.
self.project = ko.observable(); // initiated with "each" loop hook-up in viewmodel.
self.projectSettings = ko.computed(function () {
var project = self.project();
if (project) {
var proset = project.settings();
return proset;
}
return null;
});
self.useProjectSettings = ko.observable(data.useProjectSettings || true);
self.hasLocalSettings = ko.observable(false); // initiated with each loop hook-up in viewmodel.
self.activeSettings = ko.computed(function () {
return self.useProjectSettings() ? self.projectSettings() : self.settings();
});
return self;
};
Project = function (data) {
var self = this;
self.projectID = data.projectID;
self.title = ko.observable(data.title);
// settings
self.settings = ko.observable();
return self;
};
Setting = function (data) {
var self = this;
self.settingID = data.settingID;
self.projectID = data.projectID;
self.textID = data.textID;
self.isVisible = ko.observable(data.isVisible);
self.isProjectDefault = ko.observable(data.isProjectDefault || true);
return self;
};
ViewModel = function (myprojects, mysettings, mytexts) {
var self = this,
koEach = ko.utils.arrayForEach, koFirst = ko.utils.arrayFirst, koFilter = ko.utils.arrayFilter;
self.selectedText = ko.observable();
//data - load
self.Projects = ko.observableArray(
ko.utils.arrayMap(myprojects, function (item) {
return new Project(item);
}));
self.Settings = ko.observableArray(
ko.utils.arrayMap(mysettings, function (item) {
return new Setting(item);
}));
self.Texts = ko.observableArray(
ko.utils.arrayMap(mytexts, function (item) {
return new Text(item);
}));
//alert("self.Projects()[0].projectID=" + self.Projects()[0].projectID );
// hook up 'settings' on 'project'
koEach(self.Settings(), function (s) {
if (s.isProjectDefault()) {
var project = koFirst(self.Projects(), function (p) {
return p.projectID === s.projectID;
});
if (project) {
project.settings(s);
}
}
});
//alert("self.Texts()[0].textID=" + self.Texts()[0].textID + ", self.Texts()[0].title()=" + self.Texts()[0].title() );
//hook up 'project' on 'texts'
koEach(self.Texts(), function (t) {
var project = koFirst(self.Projects(), function (p) {
return p.projectID === t.projectID;
});
t.project(project);
// initiate default publishingSettings for textbatch
var initsettings = project.settings();
t.settings(initsettings);
});
// hook up 'settings' on 'text'
koEach(self.Settings(), function (s) {
if (!s.isProjectDefault()) {
var text = koFirst(self.Texts(), function (t) {
return t.textID === s.textID;
});
if (text) {
text.settings(s);
}
}
});
};
// console log
var consoleLine = "<p class=\"console-line\"></p>";
console = {
log: function (text) {
$("#console-log").append($(consoleLine).html(text));
}
};
// input
var projects = [{ projectID: 0, title: 'project 0' }, { projectID: 1, title: 'project 1' }];
var settings = [
{ settingID: 0, projectID: 1, textID: null, isVisible: true, isProjectDefault: true },
{ settingID: 1, projectID: null, textID: 0, isVisible: true, isProjectDefault: false },
{ settingID: 2, projectID: 1, textID: 1, isVisible: false, isProjectDefault: false }
];
var texts = [{ textID: 0, projectID: 0, title: 'first text' }, { textID: 1, projectID: 1, title: 'second text' }];
// binding
ko.applyBindings(new ViewModel(projects, settings, texts));
这是我的HTML:
<select data-bind="options: $root.Texts, optionsCaption: 'choose...', optionsText: 'title', value: selectedText"></select>
<br/>
Selected: <span data-bind="text: $root.selectedText().title"></span><br>
Selected2: <span data-bind="text: $root.selectedText().title"></span><br>
TextID: <span data-bind="text: selectedText().textID"></span><br>
<hr/>
<div data-bind="with: $root.selectedText">
<h2 data-bind="text:title"></h2>
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" data-bind="checked: useProjectSettings" />Use project settings
</label>
</div>
</div>
Settings for text '<span data-bind="text: title"></span>' (id='<span data-bind="value: textID"></span>').<br/><br/>
<div class="pubset" data-bind="css: {'unabled' : useProjectSettings() }">
<div class="form-group">
<div class="checkbox">
<label>
<input type="checkbox" data-bind="enable: !useProjectSettings(),checked: activeSettings().isVisible"/>
Show text
</label>
</div>
</div>
</div>
</div>
在我的示例代码中,似乎我还有另一个问题,因为它没有进展到第二个<span>
节点。小提琴here。