Có thể liên kết dữ liệu hiển thị với phủ định (hung!)) Của thuộc tính ViewModel boolean?


162

Tôi muốn sử dụng một thuộc tính trên ViewModel của mình để chuyển đổi biểu tượng nào sẽ hiển thị mà không tạo thuộc tính được tính toán riêng của nghịch đảo. Điều này có thể không?

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

ViewModel của tôi có một khoảng thời gian thuộc tính là một mảng của tháng, như thế này:

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

3
@Niko: Đây không thực sự là một câu hỏi trùng lặp. OP của câu hỏi mà bạn đề cập đã biết rằng có thể liên kết dữ liệu phủ định sự phủ định của một điều có thể quan sát được, nhưng tự hỏi tại sao nó cần được gọi như một hàm. Câu hỏi này OP ở đây không biết làm thế nào để làm điều đó ngay từ đầu và rõ ràng là không tìm thấy câu hỏi khác. Tôi rất vui vì đã tìm thấy câu hỏi này ở đây - chủ yếu là nhờ tiêu đề mô tả của nó.
Oliver

Câu trả lời:


281

Khi sử dụng một quan sát trong một biểu thức, bạn cần truy cập nó dưới dạng một hàm như:

visible: !charted()


33
Có lẽ chúng ta nên tạo một ràng buộc ẩn :) Chúng tôi đã kích hoạt và vô hiệu hóa.
John Papa

Tài liệu này có đồng ý với điều này không, hay tôi hoàn toàn hiểu nhầm trang này: knoutoutjs.com/documentation/css-binding.html
Devil's Advocate

Không bao giờ, tôi đoán "isSevere" không phải là một tài sản cũ có thể quan sát được, do đó, sự nhầm lẫn của tôi.
Người ủng hộ của quỷ

3
Khi sử dụng! Biểu đồ, bạn sẽ nhận được! [Chức năng]. [Hàm] là trung thực ,! [Hàm] trở thành sai và sẽ luôn sai nếu bạn sử dụng cú pháp đó. jsfiddle.net/datashaman/E58u2/3
datashaman

1
Họ thực sự đã thêm hiddenràng buộc trong phiên bản 3.5.0
Grin

53

Tôi đồng ý với nhận xét của John Papa rằng cần phải có một hiddenràng buộc tích hợp. Có hai lợi ích cho một hiddenràng buộc chuyên dụng :

  1. Cú pháp đơn giản hơn, tức là. hidden: chartedthay vì visible: !charted().
  2. Ít tài nguyên hơn, vì Knockout có thể quan sát chartedtrực tiếp có thể quan sát , thay vì tạo ra một computedquan sát !charted().

Nó đủ đơn giản để tạo ra một hiddenràng buộc, mặc dù, như thế này:

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

Bạn có thể sử dụng nó giống như visibleràng buộc tích hợp:

<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
điều này đã không làm việc cho tôi mà không trở lạireturn !ko.utils.unwrapObservable(valueAccessor());
Mehmet Ataş

Cảm ơn @ MehmetAtaş - Tôi đã sửa lỗi hiddenràng buộc cho mỗi bình luận của bạn. (BTW, tôi đã sử dụng CoffeeScript trong dự án của tôi vào thời điểm đó tôi đã đăng ban đầu này cú pháp CoffeeScript của không làm cho nó rõ ràng khi quay trở lại là cố ý..)
Dave

9

Nó hơi khó hiểu, như bạn phải làm

visible:!showMe()

Tôi cũng vậy

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

mô hình của tôi là

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

Kiểm tra fiddle http://jsfiddle.net/khanSharp/bgdbm/


4

Bạn có thể sử dụng ràng buộc chuyển đổi / trường hợp của tôi , bao gồm 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>

Bạn cũng có thể có nó như

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

Tôi chỉ nhận ra rằng đây là một câu hỏi cũ nhưng hy vọng nó có thể hữu ích cho ai đó.
Michael hay nhất

1

Để làm cho ràng buộc nhận biết các thay đổi đối với thuộc tính, tôi đã sao chép trình xử lý ràng buộc có thể nhìn thấy và đảo ngược nó:

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

Disclaimer: giải pháp này chỉ dành cho mục đích giải trí.

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

Tôi đã có cùng một vấn đề về cách sử dụng ngược lại với một boolean quan sát được. Tôi đã tìm thấy một giải pháp dễ dàng:

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

};

Bây giờ trên HTML của bạn, bạn nên làm điều này

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

Khi chương trình chỉ bắt đầu, "Text1" hiển thị vì "false === false là TRUE" và Text2 không hiển thị.

Hãy nói rằng chúng ta có một nút để gọi sự kiện tụ tập thay thế trên sự kiện nhấp chuột. Bây giờ Text1 sẽ không hiển thị vì "true === false là FALSE" và Text 2 chỉ hiển thị.

Một giải pháp khả thi khác có thể là sử dụng tính toán có thể quan sát được, nhưng, tôi nghĩ là một giải pháp quá phức tạp cho một vấn đề đơn giản như vậy.


-1

Cũng có thể sử dụng ẩn như thế này:

 <div data-bind="hidden: isString">
                            <input type="text" class="form-control" data-bind="value: settingValue" />
                        </div>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.