ブールViewModelプロパティの否定(「!」)にデータバインドを表示することは可能ですか?


162

ViewModelのプロパティを使用して、逆の個別の計算されたプロパティを作成せずに、表示するアイコンを切り替えたいと思います。これは可能ですか?

<tbody data-bind="foreach: periods">
  <tr>
    <td>
      <i class="icon-search" data-bind="visible: !charted, click: $parent.pie_it"></i>
      <i class="icon-remove" data-bind="visible: charted, click: $parent.pie_it"></i>
    </td>
  </tr>
</tbody>

My ViewModelには、次のように月の配列であるプロパティの期間があります。

var month = function() {
    this.charted = ko.observable(false);
};

3
@ニコ:それは本当に重複した質問ではありません。あなたが参照する質問のOPは、オブザーバブルの否定をデータバインドできることをすでに知っいますが、なぜ関数のように呼び出す必要があるのか​​疑問に思います。この質問のOPは、そもそもその方法を知りませんでしたし、明らかに他の質問も見つかりませんでした。ここでこの質問を見つけてよかったです。これは主に説明的なタイトルのおかげです。
オリバー

回答:


281

式でオブザーバブルを使用する場合は、次のような関数としてアクセスする必要があります。

visible: !charted()


33
たぶん私たちは隠しバインディングを作成する必要があります:)有効化と無効化があります。
John Papa

ドキュメントはこれに同意しませんか、またはこのページを完全に誤解していますか:knockoutjs.com/documentation/css-binding.html
Devil's Advocate

気にしないでください、 "isSevere"は観察可能ではなく単純な古いプロパティなので、私は混乱しています。
Devil's Advocate

3
!chartedを使用すると、![関数]を取得します。[関数]は真実です。![関数]はfalseになり、その構文を使用すると常にfalseになります。jsfiddle.net/datashaman/E58u2/3
datashaman '28

1
彼らは実際hiddenv3.5.0で
Grin

53

組み込みのhiddenバインディングがあるべきだというジョンパパのコメントに同意します。専用hiddenバインディングには2つの利点があります。

  1. よりシンプルな構文、すなわち。hidden: chartedの代わりにvisible: !charted()
  2. Knockoutは、観察chartedするを作成するのではなく、オブザーバブルを直接観察できるため、リソースが少なくcomputedなります!charted()

作成するのに十分簡単です hiddenただし、次のようにバインディングです。

ko.bindingHandlers.hidden = {
  update: function(element, valueAccessor) {
    ko.bindingHandlers.visible.update(element, function() {
      return !ko.utils.unwrapObservable(valueAccessor());
    });
  }
};

組み込みのvisibleバインディングと同じように使用できます。

<i class="icon-search" data-bind="hidden: charted, click: $parent.pie_it"></i>
<i class="icon-remove" data-bind="visible: charted, click: $parent.pie_it"></i>

9
これは私に戻りなしでは機能しませんでしたreturn !ko.utils.unwrapObservable(valueAccessor());
MehmetAtaş2013年

ありがとう@MehmetAtaş- hiddenあなたのコメントに従ってバインディングを修正しました。(ところで、私が最初にこれを投稿したとき、私は自分のプロジェクトでCoffeeScriptを使用していました。CoffeeScriptの構文では、復帰が意図的である場合は明確になりません。)
Dave

9

あなたがしなければならないので、それは少し混乱しています

visible:!showMe()

そう、私はやった

<span data-bind="visible:showMe">Show</span>
<span data-bind="visible:!showMe()">Hide</span>
<label><input type="checkbox" data-bind="checked:showMe"/>toggle</label>​

私のモデルは

var myModel={
    showMe:ko.observable(true)
}
ko.applyBindings(myModel);    

フィドルでチェックインhttp://jsfiddle.net/khanSharp/bgdbm/


4

あなたは私の使用することができますスイッチ/ケースが含まれ、結合case.visiblecasenot.visible

<tbody data-bind="foreach: periods">
    <tr>
        <td data-bind="switch: true">
        <i class="icon-search" data-bind="case.visible: $else, click: $parent.pie_it"></i>
        <i class="icon-remove" data-bind="case.visible: charted, click: $parent.pie_it"></i>
        </td>
    </tr>
</tbody>

次のようにすることもできます

        <i class="icon-search" data-bind="casenot.visible: charted, click: $parent.pie_it"></i>
        <i class="icon-remove" data-bind="case.visible: $else, click: $parent.pie_it"></i>

これは古い質問であることに気づきましたが、これが誰かに役立つことを願っています。
マイケルベスト

1

プロパティへの変更をバインディングに認識させるために、可視のバインディングハンドラーをコピーして反転しました。

ko.bindingHandlers.hidden = {
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        var isCurrentlyHidden = !(element.style.display == "");
        if (value && !isCurrentlyHidden)
            element.style.display = "none";
        else if ((!value) && isCurrentlyHidden)
            element.style.display = "";
    }
};

0

免責事項:このソリューションは、娯楽目的でのみ使用できます。

ko.extenders.not = function (target) {
    target.not = ko.computed(function () {
        return !target();
    });
};

self.foo = ko.observable(true).extend({ not: null });

<div data-bind="text: foo"></div>     <!-- true -->
<div data-bind="text: foo.not"></div> <!-- false -->

<!-- unfortunately I can't think of a way to be able to use:
    text: foo...not
-->

0

私はブールのオブザーバブルの反対を使用する方法について同じ問題を抱えていました。私は簡単な解決策を見つけました:

var ViewModel = function () {
var self = this;

// When program start, this is set to FALSE
self.isSearchContentValid = ko.observable(false);


self.gatherPlacesData = function () {

   // When user click a button, the value become TRUE
   self.isSearchContentValid(true);

};

あなたのHTMLでこれを行う必要があります

<p data-bind = "visible:isSearchContentValid() === false"> Text 1</p>
<p data-bind = "visible:isSearchContentValid"> Text 2</p>

プログラムが起動すると、「false === falseはTRUE」であり、Text2が表示されないため、「Text1」のみが表示されます。

クリックイベントでgatherPlacesDataを呼び出すボタンがあるとしましょう。「true === falseはFALSE」であり、Text 2のみが表示されるため、Text1は表示されません。

別の可能な解決策は、計算された観察可能なものを使用することかもしれませんが、私は非常に単純な問題の複雑すぎる解決策だと思います。


-1

このように非表示を使用することもできます:

 <div data-bind="hidden: isString">
                            <input type="text" class="form-control" data-bind="value: settingValue" />
                        </div>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.