简体   繁体   English

淘汰:上下文在observable.subscribe中的指令之前更改

[英]Knockout : context changed before the instruction in observable.subscribe

I'm trying to separate my Model from my ViewModel since I need the Model in two different ViewModel. 我试图将模型与ViewModel分开,因为我需要在两个不同的ViewModel中使用模型。 So i've tried to this : 所以我试图做到这一点:

var ConversationManager = {
    conversations: ko.observableArray([
        {id: 3, receiver:'Toto'}
    ])
};

function ConversationDialogViewModel(){
    var self = this;

    ConversationManager.conversations.subscribe(function(context){
        console.log('Before :', context); // context.test == true ???

        for(var i = 0; i < context.length; i++){
            if(context[i].id % 2 == 0 && !context[i].test){
                console.log('Insertion Called');
                context[i].test = true;
            }
        }
        console.log('After :', context);
    });

    ConversationManager.conversations.push({id: 4, receiver:'Jean'});
    ConversationManager.conversations.push({id: 5, receiver:'Paul'});
    ConversationManager.conversations.push({id: 6, receiver:'Bleu'});
}

Somehow, in the first console.log, when i push "Jean", in the browser, the variable "test" exists and is correctly set to true even before i actually tell JS to do it. 不知何故,在第一个console.log中,当我在浏览器中按“ Jean”时,即使实际告诉JS之前,变量“ test”也已存在并正确设置为true。 How is that possible ? 那怎么可能呢? And, am I correctly separating my concerns ? 而且,我是否正确分离了我的担忧?

From the documentation : 文档中

If you want to be notified of the value of an observable before it is about to be changed, you can subscribe to the beforeChange event. 如果要在要更改的可观察值之前收到通知,可以预订beforeChange事件。

You could try it this way: 您可以这样尝试:

ConversationManager.conversations.subscribe(function(context){
    // ...
}, null, "beforeChange");

When the console references an object (where you can click an arrow to open it and look at its contents), it is still a reference, not a snapshot in time. 当控制台引用一个对象(您可以在其中单击箭头以打开它并查看其内容)时,它仍然是一个引用,而不是及时的快照。 As you modify context , it doesn't matter which reference to it in the debugger you look at, they will all be the same. 修改context ,无论在调试器中查看哪个引用都无关紧要,它们都是相同的。 You need to convert it to something that is static (or put in a breakpoint) if you want to see it at a moment in time. 如果您想及时看到它,则需要将其转换为静态(或置于断点)。

 var ConversationManager = { conversations: ko.observableArray([ {id: 3, receiver:'Toto'} ]) }; function ConversationDialogViewModel(){ var self = this; ConversationManager.conversations.subscribe(function(context){ console.log('Before :', JSON.stringify(context)); // context.test == true ??? for(var i = 0; i < context.length; i++){ if(context[i].id % 2 == 0 && !context[i].test){ console.log('Insertion Called'); context[i].test = true; } } console.log('After :', JSON.stringify(context)); }); ConversationManager.conversations.push({id: 4, receiver:'Jean'}); ConversationManager.conversations.push({id: 5, receiver:'Paul'}); ConversationManager.conversations.push({id: 6, receiver:'Bleu'}); } new ConversationDialogViewModel(); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM