在加载了 requierejs 的模块中使用 knockout observables 时,我无法更新该值

when using knockout observables in modules loaded with requierejs i can't update the value

我是 knockout 的新手,我在使用 requirejs 加载的模块中使用 observables 时遇到问题。

代码非常简单,它使用 html 中声明的视图模型工作。当我使用 require 加载视图模型时,可观察变量的行为就像一个函数,所以我必须使用括号来访问变量。但是当我尝试使用输入更改值时,什么都没有发生。此外,当我从回调函数向可观察数组添加值时,UI 不会更新。

有没有一种方法可以加载模块并继续使用不带括号的变量?

我尝试使用构造函数和共享对象实例,但问题仍然存在。

index.html

<div data-bind="component: 'cmp'"></div>
<script>
    (document).ready(function () {
         ko.components.register('cmp', {require: '../Models/cmp'});
         ko.applyBindings();
    });
<script>

/Models/cmp.js

define(['knockout-3.4.0'], function (ko) {
function MyComponentViewModel(params) {
    self = this;        
    self.firstName = ko.observable("John");
    self.lastName = ko.observable("Doe");
    self.sel = ko.observableArray(['France', 'Germany', 'Spain']);     
}
return {
    viewModel: MyComponentViewModel,
    template: { require: 'text!../Models/cmp.html' }                
};  

});

/Models/cmp.html

<p>First name: <strong data-bind="text: firstName">todo</strong></p>
<p>Last name: <strong data-bind="text: lastName()">todo</strong></p>
<select data-bind="options: sel()" class="form-control" id="sel"></select>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName()" /></p>

结果:

First name: function c(){if(0 ....

Last name: Doe

我猜您正在 index.html 文件中加载 require.js 和 knockout.js。 ko 在你的 index.html 中使用,所以它必须在全局范围内。如果是这种情况,knockout 将被加载两次,并且可能会导致与您描述的类似的问题。

无论如何,我会在您的 index.html 文件中使用 require 入口点,并将 ko 作为依赖项注入。

<html>
<head>
<title>test</title>
</head>
<body>
<script src="require.js"></script>
<div data-bind="component: 'cmp'"></div>
<script>
    require(["knockout-3.4.0"], function(ko) {
        ko.components.register('cmp', {require: 'Models/cmp'});
        ko.applyBindings();
    });
</script>
</body>
</html>

cmp.js(注意 html 文件的路径更改)

define(['knockout-3.4.0'], function (ko) {
    function MyComponentViewModel(params) {
        self = this;        
        self.firstName = ko.observable("John");
        self.lastName = ko.observable("Doe");
        self.sel = ko.observableArray(['France', 'Germany', 'Spain']);     
    }
    return {
        viewModel: MyComponentViewModel,
        template: { require: 'text!Models/cmp.html' }                
    };  
});

cmp.html

<p>First name: <strong data-bind="text: firstName">todo</strong></p>
<p>Last name: <strong data-bind="text: lastName">todo</strong></p>
<select data-bind="options: sel()" class="form-control" id="sel"></select>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>

在项目的根目录下,我有 index.html、knockout-3.4.0.js、require.js 和 text.js。我将 cmp.js 和 cmp.html 包含在 "Models" 子文件夹 (rootDir\Models) 中。

最后一点,如果您大量使用 knockout.js,则在全局范围(脚本标记)中加载 knockout.js 并且不将其用作每个 [中的依赖项可能更容易 javascript模块。