0

私は次の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());

基本的に、それぞれ 4 つの要素を持つ 2 つの observableArray の observableArray を作成しています。

私は次の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>

バインドされている observableArray に従って各インデックスが出力された div が作成されることを期待しています。(この場合: 4 div、すべてのインデックスが 0 以上である必要があるため)

私が実際に得るもの:空白。

JSFiddle リンクは次のとおりです: http://jsfiddle.net/qrwBE/

if ステートメントを ex: に変更するif: $index != 0と、配列にバインドされた 4 つの要素すべてが出力されますが、この場合、最初の要素 (インデックス 0) が他の 3 つの要素と一緒に出力される理由がよくわかりません。

ifステートメントを間違って使用していますか?

何が起こっているのかについての説明、および JavaScript などに関するその他のコメントは大歓迎です。

4

2 に答える 2

3

したがって、ここで調べる項目がいくつかあります。

foreach ループにインデックス値を含む div が表示されないのはなぜですか?

答えは、$index()関数であるオブザーバブルであるためです。したがって、上で示したように使用する必要があります。機能した理由if: $index != 0は、JavaScript では、0 と評価されるものは false であり、ゼロ以外は true と評価されるためです (これらの言語に精通している場合は、c/c++ のように.

したがって、これは、あなたif: $index != 0が本当に言っているところを書いたときに、$index not null or undefined?真の関数であるため、テンプレートからdivを出力し続けることを意味します。

リファクタリングの推奨事項:

foreach バインディングは、observableArray が空の場合に 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()、インタープリターのおかげで他のすべての前に定義されるため、後続のコード呼び出しは問題なく機能します。

ただし、2 番目のもの (式) は変数名のみが先頭に持ち上げられますが、割り当てはそのままの場所にとどまります。つまり、コードは次のようになります。

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

安全な賭け、それを一貫して行い、これらを混ぜ合わせて関数を書くアプローチに合わせないでください。

于 2013-02-13T05:49:59.707 に答える
1

バインディングで JavaScript 式を実行する場合、プロパティの値を取得する必要があります。

http://jsfiddle.net/wiredprarie/EWrsF/

if: $index() > 0

使用中で:

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

私は確かにあなたのコードの残りの部分を理解していません (使用している変数名とパターンを理解するのは難しいため)。

于 2013-02-13T02:19:08.973 に答える