1

私は現在、ウェブサイトのスパアプリケーションに取り組んでおり、knockout.js を使用しようとしています。これは、データおよび JavaScript ビュー モデルのアップショットを使用する dbdatacontroller API を備えた mvc プラットフォーム上にあります。私は複雑なビューモデルを持っており、主にノックアウトが初めてであるために困難に直面しています。私の最大の問題は、オブザーバブルへのアクセスにあるようです。データベースは次のように構成されています。

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

基本的に、私が何をしても、アイテムの値にアクセスできないようです。1つのブランチにアクセスした場所ならどこでも、つまり。AdvanceSearch().AnswerType().Answers、取得しようとすると、$parents[1].UserValues[].FieldValueText常に未定義のようです。私が言ったように、私はノックアウトに慣れていないので、おそらく何かが足りないだけです. または、複数のビューモデルなどを使用する必要がありますか? (もしそうなら、どうすればいいですか?) ありがとう。

4

2 に答える 2

0

君の:

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

する必要があります:

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

AdvanceSearch からAdvanceSearchsへの複数形に注意してください。

編集:

また、UserValuesは Observable Array であるため、 にアクセスすることはできませんUserValues().FieldValueText

期待される出力が何であるかを正確に確認してください。ただし、これは次のように入力を表示しますUserValue

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

注意: ID の重複を避けるために、入力の ID を別のものに変更しましたUserProfileIDUserValue

さらに遠く、

Knockouts options-bindingのドキュメントを参照してもよろしいですか。要素のデータ バインド オプションは次のselectとおりです。

options:select- これは、要素をバインドするオプションのリストです

optionsText:リスト内の各項目について、select要素に表示するプロパティ

optionsCaption:select要素の最初の/「ダミー」アイテムのテキスト

value:selectこれはオブザーバブルである必要があり、要素の現在の選択にバインドされています

valueバインドは Knockout の非常に便利な機能です。optionsValue選択したオブジェクト全体にアクセスできるため、ID について心配する必要がなくなります。

したがって、selectバインディングは次のようになります。

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

ビューモデルにオブザーバブルを追加したと仮定selectedAnswerします。

于 2012-10-01T09:45:58.300 に答える
0

あなたのコメントに基づいて、私はあなたがやろうとしていることを今知っていると思います。ViewModel とオブジェクトは非常に複雑で、説明なしでは理解しにくいため、理解しやすいように抽象化します。

オブジェクト型がBookありAuthor、コンストラクターがある場合:

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ボックスから Book を選択し、input表示を Authors 名にバインドするには、viewmodel が必要です。

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 observableこれは、大規模なデータ セットではかなり非効率になる可能性があることに注意してください。selectedBooksAuthor

編集:

実際のデモについては、このフィドルを参照してください。

于 2012-10-01T17:28:20.950 に答える