javascript - KnockoutJS if 语句有效性

标签 javascript knockout.js

我有以下 JavaScript:

function RandomViewModel() {
    var self = this;
    self.RnadomSquaresK = ko.observableArray([
        randomSquare(),
        randomSquare(),
    ]);
}

var randomSquare = function() { return ko.observable({
    innate: ko.observableArray([
        { star: "test1", Class: "starList", Style: {} },
        { star: "test2", Class: "starList", Style: {display:'inline'} },
        { star: "test3", Class: "starList", Style: {} },
        { star: "test4", Class: "starList", Style: {} }
    ])
})};

ko.applyBindings(new RandomViewModel());

它基本上是创建一个由两个 observableArray 组成的 observableArray,每个都有 4 个元素。

我有以下 html:

<script id="starTemplate" type="text/html">
    <!-- ko if: ($index >= 0) -->
    <div data-bind="text: $index, attr: { class: Class }, style: Style"></div>
    <!-- /ko -->
</script>

<div class="starList" data-bind="template: { name: 'starTemplate', foreach: RnadomSquaresK()[0]().innate }"></div>

我期望创建 div,并根据它们绑定(bind)到的 observableArray 打印它们的每个索引。 (在本例中:4 个 div,因为所有索引都应等于或大于 0)

我实际得到的是:空白。

这是 JSFiddle 链接:http://jsfiddle.net/qrwBE/

如果我将 if 语句更改为 ex: if: $index != 0,我会打印绑定(bind)到数组的所有 4 个元素,但我不太明白为什么在这种情况下第一个元素(索引 0)与其他 3 个元素一起打印。

我是否错误地使用了 if 语句?

非常欢迎对正在发生的事情进行解释,以及有关 javascript 等的任何其他评论。

最佳答案

所以这里有很多项目需要检查:

为什么 foreach 循环不显示其中包含索引值的 div?

答案是因为你$index()是一个可观察量,它们是函数。所以你必须像我上面演示的那样使用它。原因if: $index != 0之所以有效,是因为在 javascript 中,计算结果为 0 的内容为 false,任何非零计算结果为 true(如果您熟悉这些语言,就像在 c/c++ 中一样。

所以这意味着当你写if: $index != 0时你真正说的是函数 $index not null or undefined?这是正确的,因此它将继续从您的模板输出 div。

重构建议:

如果 observableArray 为空,foreach 绑定(bind)将自动处理不渲染 div 标签的问题。这意味着您可以完全删除 if 检查...这也可以解决您的问题。

<script id="starTemplate"a type="text/html">
    <div data-bind="text: $index, attr: { class: Class }, style: Style"></div>
</script>

模型更改:

让我们检查一下这个函数:

var randomSquare = function() { return ko.observable({
    innate: ko.observableArray([
        { star: "test1", Class: "starList", Style: {} },
        { star: "test2", Class: "starList", Style: {display:'inline'} },
        { star: "test3", Class: "starList", Style: {} },
        { star: "test4", Class: "starList", Style: {} }
    ])
})};

这里您返回一个可观察的对象,其中包含一个名为 innate 的属性,它是一个可观察的数组。为什么不直接删除包含在可观察对象中的内容,因为它只会使访问数组的语法变得更时髦 RnadomSquaresK()[0]().innate

与其这样,不如采用以下方法:

var randomSquare = function() { return {
       innate: ko.observableArray([
        { star: "test1", Class: "starList", Style: {} },
        { star: "test2", Class: "starList", Style: {display:'inline'} },
        { star: "test3", Class: "starList", Style: {} },
        { star: "test4", Class: "starList", Style: {} }
    ]});
})};

这将简单地访问它:RnadomSquaresK()[0].innate

何时使某些东西可观察

请记住,如果您打算在可观察的状态发生变化时向 UI 或 js 中的订阅者函数发出警报,那么您只需要将某些东西设为可观察的。否则,只需将其设置为复制值(普通的旧 js 变量)。

将函数声明与函数表达式混合的危险(提升问题): 这纯粹是一个js笔记。

这是一个函数声明function RandomViewModel() { }

这是一个函数表达式var randomSquare = function() { };

解释器处理它们的方式略有不同。第一个(声明)将被提升到其父作用域的顶部。因此在后续代码中调用RandomViewModel()将完美地工作,因为由于解释器,它是在其他所有内容之前定义的。

但是,第二个(表达式)只会将变量名称提升到顶部,但它的赋值将保留在原来的位置,这意味着您的代码将等效于:

function RandomViewModel() { }
var randomSquare;

randomSquare = function() { };

这对于您的情况来说效果很好。但是,随着您的模型变得更加复杂并且彼此之间的耦合更加紧密,您最终可能会遇到类似以下场景的问题:

function RandomViewModel() { 
    var x = randomSquare(); //<-- would throw an undefined exception here
    alert(x);
}
var model = new RandomViewModel();

var randomSquare = function() { return 5; };

发生这种情况是因为口译员提升了您的 var randomSquare到范围的顶部,但直到尝试在 RandomViewModel 中使用它之后才为其分配函数。

安全打赌,保持一致,不要混合搭配这些来编写函数。

关于javascript - KnockoutJS if 语句有效性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14845242/

相关文章:

javascript - 如何在 JavaScript 中创建字符串查询?

javascript - JQPlot 渲染垂直堆积条和水平图例的麻烦

javascript - 动态绑定(bind)li项点击事件

jquery - 使用 jQuery val() 更新 KnockoutJS 绑定(bind)文本框

javascript - Flutter:从 IEX JSON API 检索股票统计和报价列表

javascript - 有人可以分解这个匿名函数并解释一下吗?

javascript - 选择日期后打开第二个日期选择器

knockout.js - 了解 VS2013 MVC 5 SPA 模板

javascript - 如何删除 d3.behavior.drag().on ("drag",...) 事件处理程序

javascript - 何时在knockoutjs原型(prototype)中使用.bind(this)