无法将可观察的内部组件绑定到If-binding

时间:2015-08-09 00:02:55

标签: knockout.js knockout-3.0

我正在尝试使用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>

1 个答案:

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