Javascript 如何使用knockoutJS对象实现heritage
我有一个由Javascript 如何使用knockoutJS对象实现heritage,javascript,jquery,knockout.js,Javascript,Jquery,Knockout.js,我有一个由项目对象、文本对象和设置对象组成的模型。设置对象可以同时保存项目和文本的值 文本始终与项目耦合。因此,它应该继承项目s设置(如果有)。但是,如果文本本身具有设置,则用户应该能够选择使用项目默认设置还是特定于文本的设置 我在项目中遇到的问题是,更新文本本地设置也会更新项目默认设置。我想这与可观测的关系有关,但到目前为止我还无法找到这种联系 这是我的密码: Text = function (data) { var self = this; self.textID = da
项目
对象、文本
对象和设置
对象组成的模型。设置
对象可以同时保存项目
和文本
的值
文本
始终与项目
耦合。因此,它应该继承项目
s设置
(如果有)。但是,如果文本
本身具有设置
,则用户应该能够选择使用项目默认设置还是特定于文本的设置
我在项目中遇到的问题是,更新文本本地设置也会更新项目默认设置。我想这与可观测的关系有关,但到目前为止我还无法找到这种联系
这是我的密码:
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));
Text=函数(数据){
var self=这个;
self.textID=data.textID;
self.title=ko.可观察(data.title);
self.projectID=data.projectID;
//背景
self.settings=ko.observable();//通过viewmodel中的“each”循环连接启动。
self.project=ko.observable();//通过viewmodel中的“each”循环连接启动。
self.projectSettings=ko.computed(函数(){
var project=self.project();
国际单项体育联合会(项目){
var proset=project.settings();
返回进程集;
}
返回null;
});
self.useProjectSettings=ko.observable(data.useProjectSettings | | true);
self.hasLocalSettings=ko.observable(false);//在viewmodel中使用每个循环连接启动。
self.activeSettings=ko.computed(函数(){
返回self.useProjectSettings()?self.projectSettings():self.settings();
});
回归自我;
};
项目=功能(数据){
var self=这个;
self.projectID=data.projectID;
self.title=ko.可观察(data.title);
//背景
self.settings=ko.observable();
回归自我;
};
设置=功能(数据){
var self=这个;
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);
回归自我;
};
ViewModel=函数(MyProject、mysettings、MyText){
var self=这个,
koEach=ko.utils.arrayForEach,koFirst=ko.utils.arrayFirst,koFilter=ko.utils.arrayFilter;
self.selectedText=ko.observable();
//数据加载
self.Projects=ko.array(
ko.utils.arrayMap(我的项目,功能(项目){
返回新项目(项);
}));
self.Settings=ko.observearray(
ko.utils.arrayMap(mysettings,function(项)){
返回新设置(项目);
}));
self.text=ko.array(
ko.utils.arrayMap(MyText,函数(项)){
返回新文本(项目);
}));
//警报(“self.Projects()[0].projectID=“+self.Projects()[0].projectID”);
//在“项目”上连接“设置”
koEach(self.Settings(),函数){
如果(s.isProjectDefault()){
var project=koFirst(self.Projects(),函数(p){
返回p.projectID==s.projectID;
});
国际单项体育联合会(项目){
项目设置;
}
}
});
//警报(“self.text()[0].textID=“+self.text()[0].textID+”,self.text()[0].title()=“+self.text()[0].title());
//在“文本”上连接“项目”
koEach(self.text(),函数(t){
var project=koFirst(self.Projects(),函数(p){
返回p.projectID==t.projectID;
});
t、 项目(项目);
//启动textbatch的默认发布设置
var initsettings=project.settings();
t、 设置(初始设置);
});
//在“文本”上连接“设置”
koEach(self.Settings(),函数){
如果(!s.isProjectDefault()){
var text=koFirst(self.text(),函数(t){
返回t.textID==s.textID;
});
如果(文本){
文本。设置;
}
}
});
};
//控制台日志
var consoleLine=“”;
控制台={
日志:函数(文本){
$(“#控制台日志”).append($(consoleLine.html(text));
}
};
//输入
var projects=[{projectID:0,title:'project0'},{projectID:1,title:'project1'}];
变量设置=[
{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 text=[{textID:0,projectID:0,title:'first text'},{textID:1,projectID:1,title:'second text'}];
//装订
应用绑定(新的视图模型(项目、设置、文本));
这是我的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>
已选择:
已选择2:
TextID:
使用项目设置
文本“”的设置(id=“”)。
显示文本
这里的示例代码似乎还有另一个问题,因为它没有进入第二个
节点。Fiddle。我觉得您对对象结构的书面解释与实际代码结构不同。传入的数据结构似乎只与整数ID相关。是否可以通过嵌套属性实际按层次关系关联数据?那么你就不需要查找属性了。如果属性冒泡了,那就意味着你的可观察对象被引用了。因此,在分配可观察的directl之前,创建一个新副本