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

내 ViewModel에는 다음과 같이 한 달의 배열 인 속성 기간이 있습니다.

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

3
@Niko : 그것은 실제로 중복 질문이 아닙니다. 당신이 언급 한 질문의 OP는 옵저버 블의 부정을 데이터 바인딩 할 수 있다는 것을 이미 알고 있었지만 왜 그것이 함수처럼 호출되어야하는지 궁금합니다. 이 질문의 OP는 처음에 그것을 수행하는 방법을 몰랐으며 분명히 다른 질문을 찾지 못했습니다. 나는이 질문을 여기서 발견하게되어 기쁘다. 주로 설명 제목 덕분입니다.
올리버

답변:


281

표현식에서 Observable을 사용하는 경우 다음과 같은 함수로 액세스해야합니다.

visible: !charted()


33
아마도 우리는 숨겨진 바인딩을 만들어야합니다 :) 우리는 활성화하고 비활성화했습니다.
John Papa

문서가 이것에 동의하지 않거나이 페이지를 완전히 이해하지 못하고 있습니까 : knockoutjs.com/documentation/css-binding.html
Devil 's Advocate

나는 "isSevere"가 관찰 할 수있는 것이 아니라 평범한 오래된 재산이므로 혼동되는 것 같습니다.
악마의 옹호자

3
! charted를 사용하면! [함수]가 표시됩니다. [함수]는 진실입니다.! [함수]는 거짓이되고 해당 구문을 사용하면 항상 거짓이됩니다. jsfiddle.net/datashaman/E58u2/3
datashaman

1
그들은 실제로 v3.5.0hidden 에서 바인딩을 추가 했습니다
Grin

53

빌트인 hidden바인딩 이 있어야한다는 John Papa의 의견에 동의합니다 . 전용 hidden바인딩 에는 두 가지 이점이 있습니다 .

  1. 더 간단한 구문, 즉 hidden: charted대신에 visible: !charted().
  2. 녹아웃은 charteda 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());
메 흐멧 ATAS에게

감사합니다 @ MehmetAtaş- hidden귀하의 의견에 따라 바인딩을 수정했습니다 . (BTW, 나는 이것을 원래 게시 할 때 내 프로젝트에서 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>

나는 이것이 오래된 질문이라는 것을 깨달았지만 이것이 누군가에게 유용 할 수 있기를 바랍니다.
Michael Best

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 is TRUE"이고 Text2가 표시되지 않으므로 "Text1"만 표시됩니다.

click 이벤트에서 gatherPlacesData를 호출하는 버튼이 있다고 가정 해 봅시다. "true === false is 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.