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 中显示 title 属性,如下所示:

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

我尝试了三种方法来显示标题属性,但是所有这些都失败了。我错过了什么吗?


已编辑

我调整了源代码如下。我在 viewmodel 上添加了 title 属性并在 getPost 中对其进行了更新,然后我成功访问了 viewmodel 的 title 属性,而不是 post 模型上的 title 属性。

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 属性,而是 viewmodel 上的 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);

需要考虑的重要事情,我认为 RP 正在推动的是,只有在获得数据之后才能创建视图模型。

于 2012-12-10T03:09:18.793 回答