简体   繁体   English

如何从同一viewModel中的不同分支访问后代?

[英]How do I access descendants from a different branch in the same viewModel?

I am currently working on a website spa application and attempting to use knockout.js. 我目前正在研究网站水疗中心应用程序,并尝试使用淘汰表.js。 it's on an mvc platform with and a dbdatacontroller api using upshot for data and javascript view models. 它在带有dbdatacontroller api的mvc平台上,并使用upshot来存储数据和javascript视图模型。 I have a complex view model and am running into difficulty, mainly due to being new to knockout. 我有一个复杂的视图模型,并且遇到了困难,主要是因为它是淘汰赛的新手。 My biggest problem seems to be in accessing the observables. 我最大的问题似乎在于访问可观察对象。 The database is organized thusly: 数据库的组织方式如下:

    function AdvanceSearch(data) {
var self = this;
self.AdvanceSearchID = ko.observable(data.AdvanceSearchID);
self.FieldTypeEnum = ko.observable(data.FieldTypeEnum);
self.AnswerType = ko.observable(data.AnswerType);
self.UserValues = ko.observableArray(ko.utils.arrayMap(data.UserValues, function (item) {
    return new UserValue(item);
}));
upshot.addEntityProperties(self, "AdvanceSearch:#A.Lib.Repository");
};

function UserValue(data) {
var self = this;

self.UserProfileID = ko.observable(data.UserProfileID);
self.LoginID = ko.observable(data.LoginID);
self.AdvanceSearchID = ko.observable(data.AdvanceSearchID);
self.FieldValueCount = ko.observable(data.FieldValueCount);
self.FieldValueText = ko.observable(data.FieldValueText);
    upshot.addEntityProperties(self, "UserValue:#A.Lib.Repository");
});
};


function AnswerType(data) {
var self = this;
self.AnswerTypeID = ko.observable(data.AnswerTypeID);
self.AnswerTypeText = ko.observable(data.AnswerTypeText);
self.Answers = ko.observableArray(ko.utils.arrayMap(data.Answers, function (item) {
    return new Answer(item);
}));
self.AnswerSliders = ko.observableArray(ko.utils.arrayMap(data.AnswerSliders, function (item) {
    return new AnswerSlider(item);
}));
upshot.addEntityProperties(self, "AnswerType:#A.Lib.Repository");
}

function Answer(data) {
var self = this;
self.AnswerTypeID = ko.observable(data.AnswerTypeID);
self.AnswerEnum = ko.observable(data.AnswerEnum);
self.AnswerText = ko.observable(data.AnswerText);
upshot.addEntityProperties(self, "Answer:#A.Lib.Repository");
}

function AnswerSlider(data) {
var self = this;
self.SliderID = ko.observable(data.SliderID);
self.AnswerTypeID = ko.observable(data.AnswerTypeID);
self.SliderType = ko.observable(data.SliderType);
self.Seed = ko.observable(data.Seed);
upshot.addEntityProperties(self, "AnswerSlider:#A.Lib.Repository");
}

And my view model is just this: 我的视图模型就是这样:

function ASViewModel() {
// Private
var self = this;
var dataSourceOptions = {
    providerParameters: {
        url: "/api/Dating",
        operationName: "GetDatingProfile"
    },
    entityType: "AdvanceSearch:#A.Lib.Repository",
    bufferChanges: false,
    mapping: AdvanceSearch
};

// Public Properties
self.dataSource = new upshot.RemoteDataSource(dataSourceOptions)
                            .refresh();
self.AdvanceSearchs = self.dataSource.getEntities();
}

So my markup is something like 所以我的标记就像

    <ol data-bind="foreach: AdvanceSearch">
   <!-- ko if: FieldTypeEnum()===5 -->
       <select data-bind="options: AnswerType().Answers, optionsText: 'AnswerText', optionsValue: 'AnswerEnum', optionsCaption: 'Not Specified', value: UserValues().FieldValueText"></select>
   <!-- /ko -->
    <!-- ko if: FieldTypeEnum()===11 -->
        <input type="text" class="multilinetext" data-bind="attr: { id: 'value_'+AdvanceSearchID()}, value: UserValues().FieldValueText" />
    <!-- /ko -->

So basically, no matter what I do, I cannot seem to access the values of the items. 因此,基本上,无论我做什么,我似乎都无法访问项目的值。 Anywhere I have accessed the one branch, ie. 我访问过一个分支的任何地方,即。 AdvanceSearch().AnswerType().Answers , trying to get $parents[1].UserValues[].FieldValueText seems always to be undefined. AdvanceSearch().AnswerType().Answers ,试图获取$parents[1].UserValues[].FieldValueText似乎总是未定义。 Like I said, I'm new to knockout, so I'm probably just missing something. 就像我说的,我是淘汰赛的新手,所以我可能只是想念一些东西。 Or should I be using multiple viewmodels or something similar? 还是我应该使用多个视图模型或类似的东西? (And if so, how would I do that?) Thanks. (如果是这样,我该怎么做?)谢谢。

Your: 你的:

<ol data-bind="foreach: AdvanceSearch">

needs to be: 需要是:

<ol data-bind="foreach: AdvanceSearchs">

Note the pluralisation of AdvanceSearch to AdvanceSearchs 注意AdvanceSearch到AdvanceSearchs的复数形式

Edit: 编辑:

Also, UserValues is an Observable Array, hence you cannot access UserValues().FieldValueText . 另外, UserValues是一个可观察的数组,因此您无法访问UserValues().FieldValueText

Note sure exactly what your expected output is, but this displays an input per UserValue : 请注意,请确定您的预期输出是什么,但这将显示每个UserValue的输入:

<!-- ko foreach: UserValues -->
    <input type="text" class="multilinetext" data-bind="attr: { id: 'value_'+UserProfileID()}, value: FieldValueText" />
<!-- /ko -->

NB: I've changed, the ID of the input to something else to avoid duplicate IDs -- this assumes UserProfileID is unique per UserValue 注意:我已将输入的ID更改为其他名称以避免ID重复-假设UserProfileID对于每个UserValue都是唯一的

Further, 进一步,

May I refer you to the documentation for Knockouts options-binding . 请允许我参考Knockouts options-binding的文档。 Your data-bind options for a select element are: select元素的数据绑定选项为:

options: - This is the list of options to bind the select element to options: -这是将select元素绑定到的选项列表

optionsText: For each item in the list, the property to display in the select element optionsText:对于列表中的每个项目,显示在select元素中的属性

optionsCaption: The text for the first/'dummy' item of the select element optionsCaption: select元素的第一个/“虚拟”项目的文本

value: this should be an observable and is bound to the current selection of the select element value:这应该是可观察的,并且绑定到select元素的当前选择

The value binding is a very handy feature of Knockout. value绑定是Knockout的一个非常方便的功能。 It removes the need to worry about IDs -- and thus optionsValue -- as you have access to the entire selected object. 由于您可以访问整个选定的对象,因此无需担心ID(因此也不必担心optionsValue

So your select binding can look like: 因此,您的select绑定如下所示:

<select data-bind="options: AnswerType().Answers,
                   optionsText: 'AnswerText',
                @* optionsValue: 'AnswerEnum', *@
                   optionsCaption: 'Not Specified',
                   value: selectedAnswer"></select>

Assuming you've added an observable selectedAnswer to your viewmodel. 假设您已向视图模型添加了一个可观察的selectedAnswer

Based on your comments, I think I now know what you're trying to do. 根据您的评论,我想我现在知道您要执行的操作。 I am going to abstract it so that it is easier to follow as your ViewModel and Objects are very complex and not easy to understand without explanation. 我将其抽象化,以便您的ViewModel和Objects非常复杂并且不加解释就不容易理解,因此易于理解。

If you have object types, Book and Author with constructors: 如果您有对象类型,则使用构造函数的BookAuthor

function Book(data) {
    this.ISBN = ko.observable( data.ISBN );
    this.Title = ko.observable( data.Title );
    this.AuthorID = ko.observable( data.AuthorID );
    /* other properties */
}

function Author(data) {
    this.AuthorID = ko.observable( data.AuthorID );
    this.Name = ko.observable( data.Name );
    /* other properties */
}

To select a Book from a select box and have a input display bound to the Authors name, you will need the viewmodel: 要从中选择一本书select框,并有一个input绑定到作者名称显示,你需要的视图模型:

var vm = {};
vm.books = ko.observableArray( /* initial data */ );
vm.authors = ko.observableArray( /* initial data */ );
vm.selectedBook = ko.observable(null);
vm.selectedBooksAuthor = ko.computed( function() {
    var authors = vm.authors(),
        selectedBook = vm.selectedBook();
    if( !selectedBook ) return null; // cannot get .AuthorID() if selectedBook == null
    var id = selectedBook.AuthorID();
    for( var a in authors ) {
        if( authors[a].AuthorID() == id )
            return authors[a];
    }
})

And your HTML: 而您的HTML:

<select data-bind="options: books,
                   optionsText: 'Title',
                   optionsCaption: 'Select a book...',
                   value: selectedBook"></select>
<!-- ko with: selectedBooksAuthor -->
<input type="text" data-bind="value: Name" />
<!-- /ko -->

Please note, this can get pretty inefficient over large sets of data -- look into using a better search algorithm (rather than the 'linear' used here) for your computed observable ie selectedBooksAuthor 请注意,这在处理大量数据时可能会非常低效-考虑使用更好的搜索算法(而不是此处使用的“线性”搜索算法)来computed observableselectedBooksAuthor

EDIT: 编辑:

Please see this fiddle for a working demonstration. 请参阅此小提琴以进行有效的演示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM