簡體   English   中英

如何從同一viewModel中的不同分支訪問后代?

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

我目前正在研究網站水療中心應用程序,並嘗試使用淘汰表.js。 它在帶有dbdatacontroller api的mvc平台上,並使用upshot來存儲數據和javascript視圖模型。 我有一個復雜的視圖模型,並且遇到了困難,主要是因為它是淘汰賽的新手。 我最大的問題似乎在於訪問可觀察對象。 數據庫的組織方式如下:

    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");
}

我的視圖模型就是這樣:

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();
}

所以我的標記就像

    <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 -->

因此,基本上,無論我做什么,我似乎都無法訪問項目的值。 我訪問過一個分支的任何地方,即。 AdvanceSearch().AnswerType().Answers ,試圖獲取$parents[1].UserValues[].FieldValueText似乎總是未定義。 就像我說的,我是淘汰賽的新手,所以我可能只是想念一些東西。 還是我應該使用多個視圖模型或類似的東西? (如果是這樣,我該怎么做?)謝謝。

你的:

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

需要是:

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

注意AdvanceSearch到AdvanceSearchs的復數形式

編輯:

另外, UserValues是一個可觀察的數組,因此您無法訪問UserValues().FieldValueText

請注意,請確定您的預期輸出是什么,但這將顯示每個UserValue的輸入:

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

注意:我已將輸入的ID更改為其他名稱以避免ID重復-假設UserProfileID對於每個UserValue都是唯一的

進一步,

請允許我參考Knockouts options-binding的文檔。 select元素的數據綁定選項為:

options: -這是將select元素綁定到的選項列表

optionsText:對於列表中的每個項目,顯示在select元素中的屬性

optionsCaption: select元素的第一個/“虛擬”項目的文本

value:這應該是可觀察的,並且綁定到select元素的當前選擇

value綁定是Knockout的一個非常方便的功能。 由於您可以訪問整個選定的對象,因此無需擔心ID(因此也不必擔心optionsValue

因此,您的select綁定如下所示:

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

假設您已向視圖模型添加了一個可觀察的selectedAnswer

根據您的評論,我想我現在知道您要執行的操作。 我將其抽象化,以便您的ViewModel和Objects非常復雜並且不加解釋就不容易理解,因此易於理解。

如果您有對象類型,則使用構造函數的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 */
}

要從中選擇一本書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];
    }
})

而您的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 -->

請注意,這在處理大量數據時可能會非常低效-考慮使用更好的搜索算法(而不是此處使用的“線性”搜索算法)來computed observableselectedBooksAuthor

編輯:

請參閱此小提琴以進行有效的演示。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM