使用“with”绑定的Knockout js组件表现不尽如人意

时间:2015-11-11 05:39:02

标签: knockout.js knockout-3.2

我有以下代码来自我设置的JSFiddle:https://jsfiddle.net/ktce56hr/2/

var RootViewModel = function() {
    var self = this;
    this.rootText = ko.observable('default text');
    this.rootFunc = function() {
        alert("root func!");
    };
}

ko.components.register('root', {
    viewModel: function(model) {
        var self = this;
        this.rootViewModel = model;
        this.title = ko.observable('default title');
    },
    template: { element: 'root_template' }
});

$(function () {
    ko.applyBindings(new RootViewModel());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>

<div data-bind="component: { name: 'root', params: { model: $root } }"></div>

<script id="root_template" type="text/html">
    <div>
        <span data-bind="text: title"></div>
        <div data-bind="with: rootViewModel">
            <input type="text" data-bind="value: rootText" />
            <button data-bind="click: rootFunc">Go</button>
        </div>
    </div>
</script>

运行此代码时,我收到以下错误:

Uncaught ReferenceError: Unable to process binding "with: function (){return rootViewModel }"
Message: Unable to process binding "value: function (){return rootText }"
Message: rootText is not defined

有人可以解释为什么我不能在组件视图模型上使用'rootViewModel'属性设置绑定上下文吗?

1 个答案:

答案 0 :(得分:1)

您正在声明组件实例:

<div data-bind="component: { name: 'root', params: { model: $root } }"></div>

params将是viewmodel构造函数的第一个参数。对于viewmodel构造函数,它看起来像这样:

"model": {
  "rootText": "default text"
}

它返回的viewmodel将是:

{
  "rootViewModel": {
    "model": {
      "rootText": "default text"
    }
  },
  "title": "default title"
}

当然,在您的视图中访问title有效。但在with: rootViewModel内,它不会包含rootText

修复很简单:

<div data-bind="component: { name: 'root', params: $root }"></div>

&#13;
&#13;
var RootViewModel = function() {
    var self = this;
    this.rootText = ko.observable('default text');
    this.rootFunc = function() {
        alert("root func!");
    };
}

ko.components.register('root', {
    viewModel: function(model) {
        var self = this;
        this.rootViewModel = model;
        this.title = ko.observable('default title');
    },
    template: { element: 'root_template' }
});

$(function () {
    ko.applyBindings(new RootViewModel());
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>

<div data-bind="component: { name: 'root', params: $root }"></div>

<script id="root_template" type="text/html">
    <div>
        <span data-bind="text: title"></div>
        <div data-bind="with: rootViewModel">
            <input type="text" data-bind="value: rootText" />
            <button data-bind="click: rootFunc">Go</button>
        </div>
    </div>
</script>
&#13;
&#13;
&#13;

P.S。:rootFunc仍存在类似的问题,但我相信你可以解决这个问题。