Bool ViewModel özelliğinin olumsuzlaması (“!”) İçin görünür veri bağlama mümkün müdür?


162

Tersine ayrı bir hesaplanan özelliği oluşturmadan hangi simgenin görüntüleneceğini değiştirmek için ViewModel'imde bir özellik kullanmak istiyorum. Mümkün mü?

<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>

Benim ViewModel, ay dizisi gibi bir özellik dönemleri vardır, şöyle:

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

3
@Niko: Bu gerçekten yinelenen bir soru değil. Bahsettiğiniz sorunun OP'si, gözlemlenebilir bir kişinin olumsuzlanmasını veriye bağlamanın mümkün olduğunu zaten biliyordu , ancak bunun neden bir işlev olarak adlandırılması gerektiğini merak ediyor. Bu sorunun OP'si ilk etapta bunu nasıl yapacağını bilmiyordu ve açıkçası başka bir soru bulamadı. Bu soruyu burada bulduğuma sevindim - çoğunlukla açıklayıcı başlığı sayesinde.
Oliver

Yanıtlar:


281

Bir ifadede gözlemlenebilir bir ifadeyi kullanırken ifadeye aşağıdaki gibi bir işlev olarak erişmeniz gerekir:

visible: !charted()


33
Belki gizli bir bağlayıcı yapmalıyız :) Etkinleştirip devre dışı bıraktık.
John Papa

Belgeler buna katılmıyor mu yoksa bu sayfayı tamamen yanlış mı anlıyorum: knockoutjs.com/documentation/css-binding.html
Şeytan'ın Avukatı

Boşver, sanırım "isSevere" gözlemlenebilir değil, sade eski bir mülktür, bu yüzden karışıklığım.
Şeytan'ın Avukatı

3
! Charted kullanırken! [Function] işlevini görürsünüz. [İşlev] doğrudur,! [İşlev] yanlış olur ve sözdizimini kullanırsanız her zaman yanlış olur. jsfiddle.net/datashaman/E58u2/3
datashaman

1
Aslında v3.5.0'dahidden bağlamayı eklediler
Grin

53

John Papa'nın yerleşik bir hiddenbağlayıcı olması gerektiğine ilişkin yorumuna katılıyorum . Özel bir hiddenbağlamanın iki avantajı vardır :

  1. Daha basit sözdizimi, yani. hidden: chartedyerine visible: !charted().
  2. Daha az kaynak, çünkü Nakavt gözlemlemek için bir gözlemlemek chartedyerine gözlemlenebilir doğrudan computedgözlemleyebilir !charted().

Bununla hiddenbirlikte, böyle bir bağlayıcı oluşturmak için yeterince basit :

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

Dahili visiblebağlama gibi kullanabilirsiniz :

<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
bu benim için geri dönmeden işe yaramadıreturn !ko.utils.unwrapObservable(valueAccessor());
Mehmet Ataş

Teşekkürler MehmetAtaş - Yorumunuzdaki hiddenbağlamayı düzelttim . (BTW, bunu başlangıçta yayınladığımda projemde CoffeeScript kullanıyordum. CoffeeScript'in sözdizimi bir dönüş kasıtlı olduğunda bunu açıkça ortaya koymuyor.)
Dave

9

Yapmanız gerektiği için biraz kafa karıştırıcı

visible:!showMe()

ben de yaptım

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

benim modelim

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

Keman kontrol http://jsfiddle.net/khanSharp/bgdbm/


4

Ve içeren switch / case bağlamamı kullanabilirsiniz .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>

Ayrıca şu şekilde olabilir:

        <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>

Bunun eski bir soru olduğunu fark ettim ama umarım bu birileri için faydalı olabilir.
Michael Best

1

Bağlamanın özellikteki değişikliklerden haberdar olmasını sağlamak için, görünür bağlayıcı işleyicisini kopyaladım ve ters çevirdim:

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

Feragatname: Bu çözüm yalnızca eğlence amaçlıdır.

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

Bir boolean gözlemlenebilir karşıtının nasıl kullanılacağı konusunda da aynı sorunu yaşıyordum. Kolay bir çözüm buldum:

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);

};

Şimdi HTML'nizde bunu yapmalısınız

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

Program başlatıldığında "false === false DOĞRU" olduğundan ve Metin2 görünmediğinden yalnızca "Metin1" görünür.

Diyelim ki, tıklama olayı için gatherPlacesData'yı çağıran bir düğmemiz var. Artık "true === false YANLIŞ" ve Metin 2 yalnızca görünür olduğu için Text1 görünmez.

Başka bir olası çözüm bilgisayarlı gözlemlenebilir kullanmak olabilir, ancak bence çok basit bir sorun için aşırı karmaşık bir çözüm.


-1

Ayrıca gizli gibi kullanabilirsiniz :

 <div data-bind="hidden: isString">
                            <input type="text" class="form-control" data-bind="value: settingValue" />
                        </div>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.