刷新Breeze中的导航属性

时间:2013-05-21 22:02:35

标签: knockout.js breeze

很抱歉,如果这是重复,但我正在阅读Breezejs.com上的文档,我想看看我是否可以对“最佳实践”进行一些阐述

我正在使用.extend在父对象上加载一些导航属性。当我想将实体添加到该可观察数组时,我正在使用模态弹出窗口。我看到在我的视图中添加了调用模态的空白实体,但是当我在创建实体后关闭模态并保存可观察数组时不会更新并且只是将主页面的新实体留空。

http://www.breezejs.com/documentation/navigation-properties说使用.push()进入Observable数组会将对象添加到数组中,所以只是想知道我是正确地做这个还是有更好的方法。它看起来很有趣的原因是我必须将实体从我的模态返回到我的父视图然后推送它,并且认为可能有更好的方法。

修改

从我的父视图模型中,我使用Durandal.js的app.js来显示模态。

var addComment = function () {
    rfcommentcreate.responseFormId(responseForm().id());
    app.showModal(rfcommentcreate).then(function (modalResult) {
        if (!modalResult) { datacontext.cancelChanges(); return false; }
        console.log(modalResult);  // Just to make sure the result is not null and of the right type
        responseForm.responseFormResponseFormComments.push(modalResult);
        return true;
    });
};

当我保存模态时,我将创建的对象传回。

    datacontext.saveChanges()
        .fail(initFailed)
        .fin(complete);

    function complete() {
        self.modal.close(responseFormComment());  // responseFormComment is the entity that I work on in the modal
    }

ResponseForm.ResponseFormResponseFormComments是ResponseForm的导航属性。

上面的代码将实体添加到Breeze的实体管理器中,但Knockout在创建后没有跟踪它。这似乎是一个真实的陈述,因为在我的父视图的Html中,我看到类似这样的东西

  

:@

来自HTML代码

<span data-bind="text: user().fullName"></span> : <span data-bind="text: message"></span> @ <span data-bind="DateTime: commentDt"></span>

在模态

中创建实体之后

根据breezejs.com上的导航属性页面,如果我正确地解释它,工作。

答:它没有,可能是我的错 B:有没有更好的方法来跟踪导航属性而不必将它们“推”到数组中?

  

请注意,我们推送到Orders而不是Orders()。

3 个答案:

答案 0 :(得分:2)

不确定您到底在做什么,但您不需要重新查询,保存和刷新,以获取您的实体。我猜你的视图模型有一些问题。尝试在没有任何UI的情况下执行添加/推送逻辑,并查看问题是否消失。我的猜测是它会。如果是这样,那么你需要仔细看看你的绑定逻辑。

答案 1 :(得分:2)

KO可能存在时间问题。我知道它是kludgy但你可能会尝试以下(顺便说一句,我更改了函数参数的名称,因为modalResult对我来说不直观):

app.showModal(rfcommentcreate).then(function (comment) {
        if (!comment) { datacontext.cancelChanges(); return false; }
        console.log(comment);  // Just to make sure the result is not null and of the right type
        responseForm.responseFormResponseFormComments.push(comment);
        return Q.delay(true,5); // return true after 5 ms to get another JS event loop cycle in.
    });

我的建议是在最后一行:

return Q.delay(true,5); // return true after 5 ms to get another JS event loop cycle in.

请参阅Q API reference中的Q.delay方法。我正在做的是让KO有机会听到Breeze更新阵列所引发的事件,并做出相应的回应。

如果有从ResponseFormCommentResponseForm的后退导航,请不要认为我会进入导航属性(它真的被称为responseFormResponseFormComments吗?“responseForm”两次?)并不是说有什么不妥。

我宁愿写:

comment.responseForm(responseForm); // entity assignment

comment.responseFormId(responseForm.id); // foreign key assignment

两者都有更新responseForm评论集的预期副作用。

但回到主要问题......尝试延迟,让我们知道是否有效。有时KO和Breeze的时机混乱。

答案 2 :(得分:1)

感谢沃德的帮助,我能够更好地指出问题所在。必须使用.push是一个无论如何都没有真正起作用的工作。我的问题是我在创建实体并在创建它时分配导航属性,实际上我需要创建它然后分配导航属性 -

// *Goto the data context and create a 'comment' and assign the current user*    

rfcommentcreate.responseFormComment(datacontext.createResponseFormComment(shell.currentUser()));

// *Assign the navigation property back to the current responseForm after creation*

rfcommentcreate.responseFormComment().responseForm(responseForm());
// *Show the modal, while making edits in the modal Knockout is still bound back to the parent properly*

app.showModal(rfcommentcreate).then(function (comment) {
        if (!comment) { datacontext.cancelChanges(); return false; } // If user cancels the dialog cancel changes (actually probably not needed)
        return true;
    });

在我展示模态之前,然后创建链接回传入的responseForm的注释,我认为它打破了父级的Knockout绑定。