如何使用knockoutJS对象实现遗产

时间:2015-05-22 09:56:19

标签: javascript jquery knockout.js

我有一个由project对象,text对象和setting对象组成的模型。 settings对象可以包含projectstexts的值。

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

0 个答案:

没有答案