我正在尝试使用if-binding有条件地加载组件。但是,我无法使用下面的构造更改分配给if-binding的observable的值,因为我认为应该更改observable的函数位于视图模型之外。我最初这样做是因为这是在KnockoutJS网站的示例中所做的:
define(["jquery", "knockout", "ko-postbox",
"text!./parent.html"], function($, ko, kopost, template) {
ko.postbox.subscribe("child-click", function(newValue) {
ParentViewModel.prototype.displayChildContent(newValue);
}, this);
function ParentViewModel() {
//
// I NEED TO CHANGE THIS FROM OUTSIDE THE VIEW MODEL
//
this.childClicked = ko.observable(false);
}
ParentViewModel.prototype.displayParentContent = function(value) {
switch (value.toLowerCase()) {
default:
break;
}
};
ParentViewModel.prototype.displayChildContent = function(value) {
switch (value.toLowerCase()) {
case "child1":
alert();
//
// I NEED TO CHANGE OBSERVABLE HERE
//
break;
default:
break;
}
};
return { viewModel: ParentViewModel, template: template };
});
然后我尝试这样做:我将函数放在视图模型中,然后在一个变量中分配视图模型。注意返回值:我使用“instance”而不是通常的“viewModel”,因为当我使用“viewModel”时,会出现错误“Uncaught Error:Component'parent':Unknown viewModel value:[object Object]”,还有,它建造了两次。
define(["jquery", "knockout", "ko-postbox",
"text!./parent.html"], function($, ko, kopost, template) {
ko.postbox.subscribe("child click", function(newValue) {
model.displayChildContent(newValue);
}, this);
function ParentViewModel() {
var self = this;
self.childClicked = ko.observable(false);
self.displayChildContent = function(value) {
switch (value.toLowerCase()) {
case "child1":
alert();
self.childClicked(true);
break;
default:
break;
}
};
}
var model = new ParentViewModel();
return { instance: model, template: template };
});
当我这样做时,if-binding不起作用。错误是“Uncaught ReferenceError:无法处理绑定”如果:function(){return childClicked}“ 消息:未定义childClicked“
这是父HTML:
<div id="container">
<!-- ko if: childClicked -->
<!-- ko component: {name: "parent"} --><!-- /ko -->
<!-- /ko -->
</div>
答案 0 :(得分:2)
如果我理解正确,您希望能够从内部和外部控制组件的渲染。诀窍是use params将控制observable传递给组件。
在此示例中,父级中的复选框控制组件的呈现,但该组件还具有“隐藏我”按钮,该按钮通过相同的控制可观察对象触发取消呈现。
由于片段转轮似乎现在已经下降了,这与小提琴一样:http://jsfiddle.net/tje9e2yy/
function ChildViewModel(params) {
this.hideMe = function() {
params.show(false);
};
}
ko.components.register('child-component', {
viewModel: ChildViewModel,
template: {
element: 'child-template'
}
});
var vm = {
childClicked: ko.observable(false)
};
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<template id="child-template">
<button data-bind="click:hideMe">Hide Me</button>
</template>
<div id="container">
<input type="checkbox" data-bind="checked:childClicked" />
<!-- ko if: childClicked -->
<!-- ko component: {name: "child-component", params:{show:childClicked}} -->
<!-- /ko -->
<!-- /ko -->
</div>