从视图模型外部调用knockout.js中的函数


Calling function in knockout.js from outside view model

我使用的是CakePHP 2.3.8,我试图从knockout.js视图模型中调用一个函数,但我很难理解发生了什么。

如果(在PHP中)设置了一个特定的变量,那么我想显示一个div,但我很难让它工作。当我从PHP代码中调用它时,div不会显示,但是方法中会触发一条警告消息,所以我知道代码正在被访问。

<div data-bind = "visible: someDiv">
    I'm visible
</div>

这是淘汰视图模型

function myViewModel(){
    var self = this;
    self.someDiv = ko.observable(false); //the div starts out hidden
    self.editing = ko.observable(false);
    //if the editing variable is changed, display someDiv
    self.editing.subscribe(function(){
        alert('edit changed'); //this alert triggers every time, even from the PHP call
        self.someDiv(true);  //someDiv only shows if I call from within the view model
    });
    //if I manually change editing to true from within the viewmodel, the div shows
    //self.editing(true);
}
ko.applyBindings(new myViewModel());

以下是启动事件序列的PHP代码

echo $this->Html->script('knockout-2.3.0');
echo $this->Html->script('viewmodel');
//if the edit variable is set, the "someDiv" should be set to true
if(isset($edit)){
    <script>
        window.vm = new myViewModel();
        window.vm.editing(true); //this will trigger the alert from the subscribe function, but the div doesn't display
    </script>
}

为什么当我从PHP中将编辑值更改为true时,div不会显示,但如果我在视图模型中更改它,它会显示?

有可能做我正在尝试的事情吗?

编辑

我正在对JS文件中的视图模型应用绑定。我不是在PHP文件中再次应用绑定。

我对"变量是设置的(在PHP中)"的意思是,数据源来自PHP,尽管最终是JavaScript设置值。我在上面的例子中把它写得很简短,所以实际上它会是这样的(并不是说它有多大区别)

//if the edit variable is set, the "someDiv" should be set to true
if(isset($edit)){
    <script>
        window.vm = new myViewModel();
        window.vm.editing(<?php echo $edit; ?>); //this will trigger the alert from the subscribe function, but the div doesn't display
        window.vm.another(<?php echo $something_else_here; ?>);
    </script>
}

为什么当我从PHP中将编辑值更改为true时,div不会显示,但如果我在视图模型中更改它,它会显示?

我没有看到任何地方你在"从php"设置它,似乎你在从JavaScript设置值。如果window.vm.editing(true);正在启动订阅功能,则它正在成功工作。此时真正的问题是,您确定只有一个VM实例绑定到DOM吗?我在您的代码中看不到任何应用绑定的地方,所以您也可以显示该代码吗?

我怀疑你的虚拟机实际上看起来像这样-

function viewModel() {
    // some code
}
ko.applyBindings(new viewModel());

或者正在初始化两次。请记住,您需要引用视图模型的同一实例。

window.vm = new myViewModel();
ko.applyBindings(window.vm);
//if the edit variable is set, the "someDiv" should be set to true
if(isset($edit)){
    <script>
        window.vm.editing(true); //this will trigger the alert from the subscribe function, but the div doesn't display
    </script>
}