1

フォルダを保持するための単純なモデルがあります。

var FolderModel = {
    folders: ko.observableArray([
        {id:'Global', uid: 'Global', name: 'Global', count:0}, 
        {id:'New', uid: 'New', name: 'New', count:0}, 
        {id:'Important', uid: 'Important', name: 'Important', count:0} 
    ]);

このモデルは以下にバインドされています:

<ul class="folder-tree" data-bind="foreach: FolderModel.folders">
    <li>
        <span data-bind="text: $data.name"></span>
        <span class="count" data-bind="text: $data.count"></span>
    </li>
</ul>

したがって、最初のビューは次のようになります。

  • グローバル(0)
  • 新規(0)
  • 重要(0)

次に、別のスクリプトでリクエストポーリングを実行しています。カウントが変更され、モデルが更新されるのを待っています。それでも、私がしたことは何もうまくいきませんでした。私が試してみました:

var match = ko.utils.arrayFirst(FolderModel.folders(), function (item) {
    return c == item.uid;
});

if (match) {
    match.count = counts[c];
}

c-これがフォルダのuidです。そこで、arrayFirstを使用して、監視可能な配列内のアイテムを取得し、更新します。

私が試した次のこと:

    $.each(FolderModel.folders(), function (index, folder) {
        var newFolder = FolderModel.folders()[index];
        newFolder.count = counts[folder.uid];
        FolderModel.folders.replace(FolderModel.folders()[index], newFolder);
    });

これも私をどこにも連れて行かず、かなりばかげているように見えますが、これは別のSOの問題で見つかりました。knockoutjsで特定のインデックス要素を置き換える方法

何が間違っているのでしょうか。また、knockout.jsで何ができなかったのでしょうか。observable array要素が変更されると、それが何かにデータバインドされると、何かも変更されると思っていました。

4

4 に答える 4

2

私があなたを正しく理解していれば、 a 内の要素のプロパティをko.observableArray更新して、配列の更新をトリガーすることはできません。これを行う必要があります:

folders: ko.observableArray([
    { id: ko.observable('Global'), uid: ko.observable('Global'), name: ko.observable('Global'), count: ko.observable(0)}
]);
于 2012-12-12T08:19:41.137 に答える
2

observableArrayKnockout が変更をキャッチしたり、メソッドを使用して配列を変更したりするためのビュー モデルとなるフォルダーが必要なだけです。

var Folder = function (id, uid, name, count) {
    // things that don't change don't need observables
    this.id = ko.observable(id);
    this.uid = ko.observable(uid);
    this.name = ko.observable(name);
    this.count = ko.observable(count);
};

var FolderModel = {
    folders: ko.observableArray([
        {id:'Global', uid: 'Global', name: 'Global', count:0}, 
        {id:'New', uid: 'New', name: 'New', count:0}, 
        {id:'Important', uid: 'Important', name: 'Important', count:0} 
    ])
};

var FolderModelNew = {
    folders: ko.observableArray([
        new Folder('Global', 'Global', 'Global', 0),
        new Folder('New', 'New', 'New', 0),
        new Folder('Important', 'Important', 'Important', 0)
    ])
};

var vm = {
    folderModel: FolderModel,
    folderModelNew: FolderModelNew
};

ko.applyBindings(vm);

vm.folderModel.folders()[1].name = '111'; // nothing
vm.folderModel.folders.splice(0, 1, {id:'Global', uid: 'Global', name: '000', count:0}); // updated
vm.folderModelNew.folders()[1].name('111'); // updated
​

フィドル: http://jsfiddle.net/Sgc5J/

于 2012-12-12T08:20:56.993 に答える
2

ko.observableArray は、アイテムがコレクションに追加または削除されたかどうかのみを追跡します。ただし、監視可能な配列内の項目を変更すると、UI は自動的に更新されません。

ドキュメントから:

キーポイント: observableArray は、オブジェクトの状態ではなく、配列内にあるオブジェクトを追跡します

したがって、コレクションcount内のプロパティを監視可能にする必要がありますfolders

var FolderModel = {
    folders: ko.observableArray([
        {id:'Global', uid: 'Global', name: 'Global', count: ko.observable(0) }, 
        {id:'New', uid: 'New', name: 'New', count: ko.observable(0) }, 
        {id:'Important', uid: 'Important', name: 'Important', count: ko.observable(0) } 
    ]);

最終的に、すべてのプロパティを更新する必要がある場合は、それらすべてを監視可能にする必要があります。KO マッピングと呼ばれる KO 用のプラグインがあり、これが役に立ちます。

更新コードは次のようになります。

var match = ko.utils.arrayFirst(FolderModel.folders(), function (item) {
    return c == item.uid;
});

if (match) {
    match.count(counts[c]); // because count is now observable
}

これは、それで遊ぶJSFiddleです。

于 2012-12-12T08:19:03.703 に答える
0

別のスクリプトから変更イベントを取得したい場合は、ノックアウトでサブスクライバーを使用する方がよいと思います

于 2012-12-12T08:13:02.793 に答える