2013-10-03 4 views
0

에서 녹아웃 확인 validatedObservable를 제거하는 방법을 내보기 모델의 특성에 observableArray 있습니다. 배열에 항목을 추가하는 버튼이 있습니다. 유효성이 확인 된 관찰 물 :는 관측 배열

self.newRate = function() { 
     var rate = new Rate({id: self.id}); 
     rate.isEditing(true); 
     rate.isNew = true; 
     rate = ko.validatedObservable(rate); 
     self.vendor().rates.push(rate); 
    }; 

이 작동합니다. 항목이 배열에 추가되고보기가 업데이트됩니다. 사용자가 행을 제거 할 수 있도록 새로 추가 된 항목 옆에 취소 링크가 있습니다.

self.editRateCancel = function (item) { 
    if (item.isNew === true) { 
     self.vendor().rates.remove(item); 
    } else { 
     item.cancelEdit(); 
     ko.utils.arrayForEach(self.unitsOfMeasure(), function (uom) { 
      if(item.cacheUnitOfMeasureID === uom.value) { 
       item.selectedUOM(uom); 
      } 
     }); 
    } 
}; 

remove(item)을 호출해도 항목이 제거되지 않습니다. 항목을 확인 된 관찰 가능 항목으로 설정하지 않으면 제거가 성공합니다. remove 함수를 보면 전달 된 항목이 (valueOrPredicate) 유형이 Object, (Rate)이고 기본 배열에서 Object, (Function)으로 반환되는 값이므로 predicate(value)이 반환되므로 항목이 제거되지 않습니다.

ko.observableArray['fn'] = { 
    'remove': function (valueOrPredicate) { 
     var underlyingArray = this.peek(); 
     var removedValues = []; 
     var predicate = typeof valueOrPredicate == "function" ? valueOrPredicate : function (value) { return value === valueOrPredicate; }; 
     for (var i = 0; i < underlyingArray.length; i++) { 
      var value = underlyingArray[i]; 
      if (predicate(value)) { 
       if (removedValues.length === 0) { 
        this.valueWillMutate(); 
       } 
       removedValues.push(value); 
       underlyingArray.splice(i, 1); 
       i--; 
      } 
     } 
     if (removedValues.length) { 
      this.valueHasMutated(); 
     } 
     return removedValues; 
    }, 

어떻게 관측 배열에서 특정 검증 관찰 가능한을 제거 할 수 있습니다

KnockoutJS 기능을 제거? 사용할 수있는 유틸리티 기능이 있습니까?

답변

0

저도 같은 문제가 발생했고이 내가 시도한 방법은 다음과 같습니다

가 관찰 배열 Rate의 인스턴스와 반환하는 계산 된 관찰로 만들기

첫 번째 방법을 각 항목의 환율은 validatedObservable입니다. 이 방법의 문제점은 배열에 항목을 추가하거나 제거 할 때마다 validatedObservable이 모두 재생성되어 효율적이지 않고 이상한 UI 동작을 유발한다는 것입니다.

SECOND APPROACH

Rate위한 추가 deleted 관찰 필드를 생성하고 visible를이 필드의 값에 기초하여 바인딩. 그런 다음 관찰 가능 어레이에서 제거되지 않지만 사용자에게는 보이지 않습니다.

세 번째 방법

Rate 및 부모보기 모델의 추가 index 필드 (하나는 self.rates 포함)을 보일 것이다 비율을 추가 0 그런 기능 설정 초기 값으로 lastIndex을 유지 만들기 이 같은 :

self.newRate = function() { 
    var rate = new Rate({id: self.id}); 
    rate.isEditing(true); 
    rate.isNew = true; 
    rate.index = lastIndex++; 
    rate = ko.validatedObservable(rate); 
    self.vendor().rates.push(rate); 
}; 

그리고 술어 기능을 사용하고 같을 것이다 항목을 제거하는 기능 :

,
self.editRateCancel = function (item) { 
    if (item.isNew === true) { 
     self.vendor().rates.remove(function (value) { 
      // remember about parenthesis after value() 
      // because it's an instance of validatedObservable() 
      // and not an instance of Rate() 
      return value().index == item.index; 
     }); 
    } else { 
     item.cancelEdit(); 
     ko.utils.arrayForEach(self.unitsOfMeasure(), function (uom) { 
      if(item.cacheUnitOfMeasureID === uom.value) { 
       item.selectedUOM(uom); 
      } 
     }); 
    } 
}; 

나는 세 번째 접근법으로 앞서 갔지만 두 번째 접근법은 당신에게도 받아 들여질 수 있습니다.

+0

세 번째 접근 방식에서 설명하는 것처럼 함수가 remove 메서드에 전달 될 수 있다는 것을 알지 못했습니다. 이것은 코드가 짧아지기 때문에 좋습니다. KnockOutJS 코드를 기반으로하는 자체 제거 함수를 작성했지만 결국 코드가 더 마음에 든다고 생각합니다. 도와 주셔서 감사합니다. – DaveB

+0

다행스럽게도 도움이 될 수 있습니다. 실제로 질문이나 코드를보고 아이디어를 생각해 낼 때까지 그 일을 할 수 있는지 몰랐습니다. 그래서 너 덕분에! –

1

방금이 문제가 발생하여 연구 결과가 여기에 표시되어 해결하기 위해 수행 한 작업을 적어 두었습니다.

녹아웃에서 foreach 바인딩을 사용하면 $ index()를 사용하여 현재 요소의 색인에 액세스 할 수 있습니다. 객체를 remove 함수로 전달하는 일반적인 메커니즘을 사용하는 대신 색인을 통과했습니다.

평소 :

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

    removeItem(item) { 
     // Tries to remove matching object, fails on observables 
     self.myArray.remove(item); 
    } 
} 

내 해결 방법 : 해결 방법에

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

    removeItem(index) { 
     // Removes 1 item at position of index 
     self.myArray.splice(index, 1); 
    } 
} 

html로이

<div data-bind="foreach: myArray"> 
    <p data-bind="text: somePropertyOfTheObject"></p> 
    // The bind call puts the index into the list of parameters of the function so it is available in the removeItems function 
    <input type="button" value="remove" data-bind="click: $root.removeItem.bind(null, $index())" /> 
</div> 
과 같을 것이다

마침내 여기에 내가 만든 바이올린이 있습니다. https://jsfiddle.net/jimmypc15/yf5h0kf2/2/