IT story

사용자 정의 녹아웃 바인딩을 위해 초기화와 업데이트 사이에 상태를 저장하는 선호하는 방법은 무엇입니까?

hot-time 2020. 12. 31. 22:53
반응형

사용자 정의 녹아웃 바인딩을 위해 초기화와 업데이트 사이에 상태를 저장하는 선호하는 방법은 무엇입니까?


현재 dom 요소에 대한 jQuery 데이터를 사용하여 상태를 저장하고 있습니다.

ko.bindingHandlers.customValue = {

    init: function init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var state = { isEditing: false };        
        $(element).focus(function focus() {
            state.isEditing = true;
        }).blur(function blur() {
            state.isEditing = false;            
        }).data("customBinding", state);

    },

    update: function update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        // ignore if updating
        if (!$(element).data("customBinding").isEditing) {
            // handle update if they are not updating                                
        }
    }

};​

DOM이 필요하지 않은 바인딩 당 상태를 저장하는 더 좋은 위치가 있습니까? bindingContext를 사용하여 바인딩의 각 인스턴스에 대한 상태를 저장할 수 있습니까?


bindingContext하지만 데이터를 통과하는 가능성 init에 대한 update결합이 트리거되는 것을 처음. 다음에 update발화하면 더 이상 거기에 없을 것입니다.

이러한 유형의 상태를 저장할 위치에는 실제로 두 가지 선택이 있습니다.

1- 당신이 말했듯이 요소에. 당신은 jQuery의 사용 $.data또는 KO이이 작업을 수행하기위한 API를 포함 ko.utils.domData.get(element, key)하고를 ko.utils.domData.set(element, key, value).

2- 적절한 경우 이러한 유형의 정보를 뷰 모델에 넣습니다. 표시 할 플래그가 isEditing뷰 모델에서 반드시 제자리를 벗어난 것은 아닙니다. 저는 개인적으로 이런 유형의 "메타 데이터"를 다음과 같은 관측 가능 항목에서 하위 관측 가능 항목으로 지정하는 것을 좋아합니다.

var name = ko.observable("Bob");
name.isEditing = ko.observable(false);

name에 바인딩 할 수 있습니다 name.isEditing.

여기에는 몇 가지 장점이 있습니다.

  • 새로운 최상위 속성을 도입하지 않기 때문에 뷰 모델을 상당히 깨끗하게 유지합니다.
  • 하위 관측 가능 항목을 상위 관측 가능 항목에 묶어 유지합니다 (필요 없음 nameIsEditing).
  • 같은과 JSON으로 전환 할 때 하위 관찰 부모 풀지 때 간단하게 삭제됩니다. 따라서 불필요한 값을 서버로 다시 보내지 않을 것입니다.ko.toJSONisEditing
  • 이 경우 뷰 모델의 다른 계산에 사용할 수 있거나 UI의 여러 요소에 대해 바인딩하는 이점도 있습니다.

요소에 데이터를 첨부하는 것은 괜찮습니다. 예를 들어 Knockout은 제어 흐름 바인딩 (if, with 등)에 대해 내부적으로이 메서드를 사용합니다.

또 다른 방법은 init함수 만 사용하고 계산 된 옵저버 블을 사용하여 업데이트를 처리하는 것입니다. 반복 바인딩 에서이 방법을 사용합니다 . 다음은 중요한 부분입니다.

ko.bindingHandlers['repeat'] = {
    'init': function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ...
        // set up persistent data
        var lastRepeatCount = 0;
        ...
        ko.computed(function() {
            var repeatCount = ko.utils.unwrapObservable(valueAccessor());
            ...
            // Remove nodes from end if array is shorter
            for (; lastRepeatCount > repeatCount; lastRepeatCount--) {
                ...
            }
            ...
            // Add nodes to end if array is longer (also initially populates nodes)
            for (; lastRepeatCount < repeatCount; lastRepeatCount++) {
                ...
            }
        }, null, {'disposeWhenNodeIsRemoved': placeholder});
        ...
    }
};

나는 종종이 패턴을 사용합니다 :

define(['knockout'], function(ko) {
  var interInstanceVariable = null;

  function Tree(element) {
    var privateInstanceVariable = null;

    function privateInstanceMethod() {}

    this.publicInstanceMethod = function() {}
  }


  ko.bindingHandlers.cannDendrogram = {
    init: function(element, valueAccessor) {
      $(element).data('tree', new Tree(element));
    },
    update: function(element, valueAccessor) {
      var tree = $(element).data('tree');
      tree.publicMethod();
    }
  };
});

나는이 질문이 오래되었다는 것을 알고 있지만 접근 방식을 찾기 위해 여기에서 우연히 발견되어 더 현대적인 ko 방법을 사용할 것이라고 생각했습니다.

bindingContext. $ data에 속성을 직접 추가하기 만하면됩니다. 잠재적 인 충돌을 피하기 위해 성가신 변수 이름 "___IsEditing"을 선택했지만 아이디어를 얻었습니다.

ko.bindingHandlers.customValue = {

init: function init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    bindingContext.$data.___IsEditing = false;        
    $(element).focus(function focus() {
        bindingContext.$data.___IsEditing = true;
    }).blur(function blur() {
        bindingContext.$data.___IsEditing = false;            
    }).data("customBinding", state);

},

update: function update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    // ignore if updating
    if (bindingContext.$data.___IsEditing) {
        // handle update if they are not updating                                
    }
}

};


I use an function to create an common scope for init and update, by defining the common data inside the function.

ReferenceURL : https://stackoverflow.com/questions/10166110/what-is-the-preferred-way-to-store-state-between-init-and-update-for-custom-knoc

반응형