【问题标题】:Where are my ko.observable properties?我的 ko.observable 属性在哪里?
【发布时间】:2015-12-08 06:11:01
【问题描述】:

我正在尝试输出到 dom data-bind="text: row.state()",但它不起作用。我不相信问题出在 json.stringify 上,它只是作为一个例子,这些值对 html 中的 ko foreach 不可见

http://jsfiddle.net/bkj37mzu/11/

thing = {
            id: 3,
            bool: ko.observable(false),
            state: ko.observable('disabled')
        }

我正在尝试在一个更大的应用程序中调试某些东西,我正在尝试做一个简单的例子来说明我的应用程序是如何崩溃的,我什至无法显示我的基本对象属性向上。

行中每个事物对象上的 2 个 ko.observable 属性在哪里?当我尝试使用“row.state()”时,它不存在,也不存在,正如您在 dom 中的字符串化“文本”中看到的那样。

请思考。

【问题讨论】:

  • 我很困惑 - JSFiddle 没有任何可观察的属性(除了数组)
  • 哎呀忘了更新,现在检查一下
  • 你看控制台对吗?错误:SyntaxError: missing } after property list。我在这里为你修好了:jsfiddle.net/bkj37mzu/8
  • 好的,现在请再次检查。这不是语法错误,我正在尝试其他方法,但忘记将所有内容放回原处。你会看到我正在对我的行进行字符串化,它们只打印出每个事物的 ID 属性。但是有 3 个属性,其中 2 个(ko observables)是不可见的......
  • 我收到了Uncaught SyntaxError: Unexpected identifier

标签: javascript knockout.js


【解决方案1】:

observables 就在那里——只是你在包含它们的对象上使用 JSON.stringfy。这将排除函数并仅序列化 POJO(普通旧 JavaScript 对象)。

正如 Jamiec 指出的那样,每个可观察对象实际上都是函数,因此它们的内容不会被序列化。

所以对于你序列化的每个盒子:

  thing = {
        id: 1,
        bool: ko.observable(false),
        state: ko.observable('disabled')
    },
    thing = {
        id: 2,
        bool: ko.observable(false),
        state: ko.observable('disabled')
    },
    thing = {
        id: 3,
        bool: ko.observable(false),
        state: ko.observable('disabled')
    }

唯一可能的输出是 3 个 ID。

如果你把你的对象转换成一个普通的 JavaScript 对象,这样这些属性就不再是函数,那么它就会像你期望的那样序列化:

var viewModel = {
	
    toggle: function (row) {
        row.bool(!row.bool);
    },
    displayState: function(row){
        
     	if(row.bool()){
            row.state('enabled');
        }   else{
            row.state('disabled');
        }
        console.log(row.state);
    },
    rows: [
        thing = {
            id: 1,
            bool: ko.observable(false),
            state: ko.observable('disabled')
        },
        thing = {
            id: 2,
            bool: ko.observable(false),
            state: ko.observable('disabled')
        },
        thing = {
            id: 3,
            bool: ko.observable(false),
            state: ko.observable('disabled')
        },
    ],

    tabs: [
        tab = 'tab1',
        tab ='tab2',
        tab = 'tab3'

    ],
}

ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<!--ko foreach: {data: tabs, as: 'tab'} -->

<div class="nav nav-tabs">
    <p>This is <span data-bind='text: tab'></span>
    </p>
</div>
    <!--ko foreach: {data: $root.rows, as: 'row'}-->
    <button class="btn btn-default" data-bind="text: JSON.stringify(ko.toJS($root.rows)), click: function(){$root.toggle(row)}"></button>
    <!--/ko-->
<!--/ko-->

请注意,foreach 中的 observables 完全可见,如下面的 sn-p 所示。正如我们所讨论的,您看不到它们的原因是因为序列化。这个例子展示了如何通过显示一个段落元素来使用它们:

var viewModel = {
	
    toggle: function (row) {
        row.bool(!row.bool);
    },
    displayState: function(row){
        
     	if(row.bool()){
            row.state('enabled');
        }   else{
            row.state('disabled');
        }
        console.log(row.state);
    },
    rows: [
        thing = {
            id: 1,
            bool: ko.observable(false),
            state: ko.observable('enabled')
        },
        thing = {
            id: 2,
            bool: ko.observable(false),
            state: ko.observable('disabled')
        },
        thing = {
            id: 3,
            bool: ko.observable(false),
            state: ko.observable('disabled')
        },
    ],

    tabs: [
        tab = 'tab1',
        tab ='tab2',
        tab = 'tab3'

    ],
}

ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<!--ko foreach: {data: tabs, as: 'tab'} -->

<div class="nav nav-tabs">
    <p>This is <span data-bind='text: tab'></span>
    </p>
</div>
    <!--ko foreach: {data: $root.rows }-->
    <button class="btn btn-default" data-bind="text: id"></button>
<p data-bind="text: state"></p>
    <!--/ko-->
<!--/ko-->

【讨论】:

  • 除非我在我的应用程序中对它们进行字符串化,否则它们就在那里。这些函数打印为 function(),它们至少在那里有属性名称。这是不正常的。即使我尝试将它们作为“行
  • 为了使其 100% 清晰,当您编写 ko.observable(blah) 时,您正在创建一个 函数JSON.stringify 将它们排除在外
  • 我之前有过字符串化的函数。我以前记录过函数,它会输入“function (){...}”或类似的东西。这不是正常行为。当我在我的应用程序中进行字符串化时,函数属性仍然存在。当我尝试在 html 中使用“text: row.state()”时,它不起作用,好像它不存在,或者没有值,或者未定义。这是不正确的。我不是第一天使用 KO。这不正常
  • 值得注意的是,简单地调用ko.toJS,然后在结果上调用JSON.stringify,或者只是调用ko.toJSON,都会做正确的事情(参见the updated fiddle)。
  • @nathanrogers 我已经将你的 cmets 标记为粗鲁,他们会离开的。你想用文明的语言再试一次吗?毕竟这里的人正在想帮助你!
【解决方案2】:

state observable 绝对在那里,它只是你输出数据的方式隐藏它们

您可以通过更新按钮上的绑定来看到这一点:

<button class="btn btn-default" data-bind="text: row.state, click: function(){$root.toggle(row)}"></button>
-------------------------------------------------^ here

http://jsfiddle.net/bkj37mzu/12/


您还应该知道,当您获取或设置可观察对象的值时,您这样做就像在调用一个函数,所以

row.bool = !row.bool;

应该是

row.bool(!row.bool())

(H/T:@CrimsonChris)

您设置state 的某些方式也是如此。总而言之,在解决了所有问题后,我认为这把小提琴做了你一开始想做的事情

http://jsfiddle.net/bkj37mzu/21/

【讨论】:

    猜你喜欢
    • 2014-12-25
    • 1970-01-01
    • 2015-01-29
    • 2018-01-29
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 2019-05-01
    • 1970-01-01
    相关资源
    最近更新 更多