0

私は次のようなビューモデルを持っています:

define(
    ['jquery', 'knockout', 'knockout.mapping', 'data/data', 'models/models'],
    function ($, ko, mapping, data, models) {
        var post =  {},

            getPost = function (param) {
                $.when(data.deferredRequest('postDetail', param.id))
                 .done(function (result) {
                     mapping.fromJS(result, {}, post);

                     console.log(result.title === post.title()); // ---> this is true
                     console.log(ko.isObservable(post.title));   // ---> this is true
                 });
            };

        return {
            post   : post,
            getPost: getPost
        };
    });

次のようにhtmlにタイトルプロパティを表示したい:

<section id="section-post-detail" class="view" >
    <div class="page-header">
        <h3 data-bind="text: post.title"></h3>    <!-- show nothing -->
        <h3 data-bind="text: post().title"></h3>  <!-- error -->
        <h3 data-bind="text: post.title()"></h3>  <!-- error -->
    </div>
</section>

title プロパティを表示する 3 つの方法を試しましたが、すべて失敗しました。何か見逃しましたか?


編集済み

以下のようにソースコードをいじりました。ビューモデルにタイトル プロパティを追加し、getPost 内で更新した後、ポスト モデルのタイトル プロパティではなく、ビューモデルのタイトル プロパティに正常にアクセスしました。

define(
        ['jquery', 'knockout', 'knockout.mapping', 'data/data', 'models/models'],
        function ($, ko, mapping, data, models) {
            var post =  {},
                title = ko.observable(''),     
                getPost = function (param) {
                    $.when(data.deferredRequest('postDetail', param.id))
                     .done(function (result) {
                         mapping.fromJS(result, {}, post);

                         title(post.title());                
                         console.log(result.title === post.title()); // ---> this is true
                         console.log(ko.isObservable(post.title));   // ---> this is true
                     });
                };

            return {
                post   : post,
                title  : title,
                getPost: getPost
            };
        });

<section id="section-post-detail" class="view" >
        <div class="page-header">
            <h3 data-bind="text: title"></h3>    
        </div>
    </section>

ただし、ご覧のとおり、data-bind="text: title" は投稿のタイトル プロパティではなく、ビューモデルのタイトル プロパティです。これは私が望むものではありません。post オブジェクトの title プロパティにアクセスしたいと思います。

私のアプローチを修正してください。

4

2 に答える 2

2

バインディングをいつ適用するかはわかりませんが、バインディングの時点では、空のオブジェクトに対してバインディングしているだけのようです。次に、AJAX リクエストが終了すると、オブザーバブルが追加されますが、postそれ自体はオブザーバブルではないため、UI は更新されません。

リクエストが次のように終了した後に applyBindings を呼び出すことを検討できます。

var vm = {
    post: ko.observable()
};    

//simulate AJAX
setTimeout(function() {
    vm.post(ko.mapping.fromJS({ title: "hello" }));    
}, 500);

ko.applyBindings(vm);

次に、次のようにバインドします。

<section id="section-post-detail" class="view" >
    <div data-bind="with: post" class="page-header">
        <h3 data-bind="text: $data.title"></h3> 
    </div>
</section>​​​​​​​​​

</p>

于 2012-12-09T17:07:50.850 に答える
1

問題は、次のように、最初にビューモデルを空のオブジェクトとして作成していることだと思います。

var post = {};

そして、次のようにビューモデルを更新しようとしています:

mapping.fromJS(result, {}, post);

ただし、 http ://knockoutjs.com/documentation/plugins-mapping.htmlにあるマッピング プラグインのドキュメントには、次のようにビューモデルを作成する必要があることが示されているようです。

var viewModel = ko.mapping.fromJS(data);
// or, in your case
var post = ko.mapping.fromJS(result);

次に、更新されたデータを取得するためにサーバーを呼び出す必要がある場合は、次のようにします。

ko.mapping.fromJS(data, viewModel);
// or, in your case
ko.mapping.fromJS(result, post);

考慮すべき重要な点は、データを取得するまでビューモデルを作成できないということです。

于 2012-12-10T03:09:18.793 に答える