用继承的数据敲除js嵌套模型

knockout js nested models with inherited data

本文关键字:js 嵌套 模型 继承 数据      更新时间:2023-09-26

我正在制作淘汰js模型。理想情况下,我希望每个页面都有子视图。模型看起来像这样:

function viewModel()
{
    var self = this;
    self.people = ko.observableArray([{"name":"Alice", parent:"Bill"},{"name":"Bill":"parent":"Candy"},{"name":"Candy","parent":""}]);
    function kidsModel()
    {
         var self = this;
         self.kids = ko.utils.arrayFilter(people, function(person) {
              return person.parent != "";
          }); 
    }
    function parentsModel()
    {
         var self = this;
         self.parents = ko.utils.arrayFilter(
                            ko.utils.arrayMap(people, function(person){
                                return person.parent;
                           })
                        , function(person) {
                              return person.parent != "";
                        });
    }
}

关键组件是我可以用子视图分割代码,并共享通过根视图过滤的数据。我发现了很多关于用漂亮的子视图在淘汰赛中设置内容的信息,但没有关于以利用淘汰赛的方式在它们之间过滤数据的信息。

您可以通过将observableArray作为参数传递给子视图模型来实现这一点。例如(这是一个有点太多的代码,但它非常简单):

// Person model
function Person(name, parent) {
    this.name = ko.observable(name);
    this.parent = ko.observable(parent);
}
// Template model, for sub views
function Template(name, data, isReady) {
    this.name = ko.observable(name);
    this.data = ko.observable(data);
    this.isReady = ko.observable(isReady);
}
// Main view model, controls templates
function ViewModel()
{
    var self = this;
    self.people = ko.observableArray([new Person("Alice", "Bill"), new Person("Bill","Candy"),new Person("Candy", "")]);
    // working with templates
    self.template = new Template('kidsTemplate', new KidsModel(self.people), true);
    self.showKids = function() {
        self.template.isReady(false);
        self.template.name('kidsTemplate');
        self.template.data(new KidsModel(self.people));
        self.template.isReady(true);
    };
    self.showParents = function() {
        self.template.isReady(false);
        self.template.name('parentsTemplate');
        self.template.data(new ParentsModel(self.people));
        self.template.isReady(true);
    };
}
// Sub-view model for Kids, takes observable array as a parameter
function KidsModel(people)
{
    var self = this;
    self.kids = ko.computed(function() {
        return ko.utils.arrayFilter(people(), function(person) {
            return person.parent() !== "";
        });
    });
    self.newKidName = ko.observable('John');
    self.newKidParentName = ko.observable('Peter');
    self.addKid = function() {
        people.push(new Person(self.newKidName(), self.newKidParentName()));
    };
}
// Sub-view model for Parents, takes observable array as a parameter
function ParentsModel(people)
{
    var self = this;
    self.parents = ko.computed(function() {
        return ko.utils.arrayFilter(
            ko.utils.arrayMap(people(), function(person){
                return person.parent();
            }),
            function(person) {
                return person;
                //return person.parent !== "";
            });
    });
}

标记是这样的:

<button data-bind="click: showKids">Show kids</button>
<button data-bind="click: showParents">Show parents</button>
<div data-bind="template: { name: template.name, data: template.data, if: template.isReady}"></div>
<script type="text/html" id="kidsTemplate">
    <!-- ko foreach: kids -->
    <div>
        Kid's Name: <b data-bind="text: name"></b>, Kid's Parent: <b data-bind="text: parent"></b>
    </div>
    <!-- /ko -->
    <div>
        New kid name: <input type="text" data-bind="value: newKidName" />, parent name: <input type="text" data-bind="value: newKidParentName" />
        <button data-bind="click: addKid">Add kid</button>
    </div>    
</script>
<script type="text/html" id="parentsTemplate">
    <!-- ko foreach: parents -->
    <div>
        Parent's Name: <b data-bind="text: $data"></b>
    </div>
    <!-- /ko -->
</script>

工作演示