无法将可观察的内部组件绑定到If绑定 [英] Can't bind observable inside component to an If-binding

查看:122
本文介绍了无法将可观察的内部组件绑定到If绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用if绑定有条件地加载组件.但是,我无法使用下面的结构来更改分配给if-binding的可观察值,因为我认为应更改可观察值的函数不在视图模型之外.我最初这样做是因为这是在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"时,会出现错误未捕获的错误:组件'父':未知的viewModel值:[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绑定不起作用.错误是未捕获ReferenceError:无法处理绑定",如果:function(){return childClicked}" 消息:未定义childClicked"

这是父HTML:

<div id="container">

    <!-- ko if: childClicked -->
    <!-- ko component: {name: "parent"} --><!-- /ko -->
    <!-- /ko -->

</div>

解决方案

如果我对您的理解正确,那么您希望能够从内部以及外部控制组件的呈现.诀窍是使用参数将可观察到的控制传递给组件.

在此示例中,父级中的复选框控制组件的呈现,但是组件还具有隐藏我"按钮,该按钮可通过相同的可观察控件触发未呈现.

由于代码片段跑步者现在似乎情绪低落,这与小提琴是一样的: 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> 

I am trying to load a component conditionally using an if-binding. However, I can't change the value of the observable that is assigned to the if-binding using the construct below since, I think, the functions that should change the observable are outside the view model. I initially did this because this is what's done in the sample in KnockoutJS's site:

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 };
});

Then I tried doing it this way: I put the functions inside the view model and then assign the view model in a variable. Notice the return value: I used "instance" instead of the usual "viewModel" because when I use "viewModel", an error appears "Uncaught Error: Component 'parent': Unknown viewModel value: [object Object]" and also, it is constructed twice.

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 };
});

When I do this, the if-binding does not work. The error is "Uncaught ReferenceError: Unable to process binding "if: function (){return childClicked }" Message: childClicked is not defined"

Here is the parent HTML:

<div id="container">

    <!-- ko if: childClicked -->
    <!-- ko component: {name: "parent"} --><!-- /ko -->
    <!-- /ko -->

</div>

解决方案

If I understand you correctly, you want to be able to control the rendering of a component from inside it as well as outside it. The trick is to use params to pass the controlling observable to the component.

In this example, the checkbox in the parent controls the rendering of the component, but the component also has a Hide Me button that triggers the un-rendering via the same controlling observable.

As the snippet runner seems to be down right now, here's the same thing as a fiddle: 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>

这篇关于无法将可观察的内部组件绑定到If绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆