Knockout ES5에 해당하는 사용자 정의 바인딩을 작성하는 방법

13849 단어 JavaScriptknockoutjs
  • 이걸 알면 observable귀속 필드를 바꿀 수 있습니다!
  • ko.expressionRewriting._twoWayBindings['binding_name'] = true; 추서
  • allBindingAccessor()['_ko_property_writers'] 현장 재작성 사용
  • 최근 KnockoutPunches, ES5 등 모든 강력한 문법 플러그인에 언어는 TypeScript, 마지막은 웹팩 등으로 제품 코드를 무장 쓰기도 했다.규모가 커져도 복잡해지지 않아 제때 귀가하는 편이다.

    Knockout ES5의 수난


    KO의 observablesetter 함수로 작용한다.이것은view→ViewModel의 변경 알림을 실현했기 때문에 문서를 읽으면 기본적으로 맞춤형 귀속observable을 전제로 제작된다.
    그러나 ES5의 속성은 진정한 의미의'속성'이기 때문에 View 모델→View의 1way 귀속으로 바뀌었다.
    예를 들어 이런 맞춤형 귀속의 경우.(value binding의 열악한 복사본)
    ko.bindingHandlers['customValue'] = {
        init: function (element, valueAccessor, allBindings) {
            var suspend = false;
    
            // ViewModel 更新する関数
            function updateModel() {
                suspend = true;
                var value = element.value;
                var modelValue = valueAccessor();
                if (ko.isObservable(modelValue)) modelValue(value);
            }
    
            // テキストボックスが変更されたら ViewModel 更新
            element.onchange = updateModel;
    
            // ViewModel が更新されたらテキストボックスに反映
            ko.computed(function() {
                if (suspend) {
                    suspend = false;
                    return;
                }
                var modelValue = ko.unwrap(valueAccessor());
                element.value = modelValue;
            });
        }
    }
    
    <input type="text" data-bind="customValue: hoge"/> ←変更しても
    <span data-bind="text: hoge"> </span> ←反映されない
    <script>
        function ExampleViewModel() {
            this.hoge = "サンプル";
            ko.track(this);
        }
        var vm = new ExampleViewModel();
        ko.applyBindings(vm);
    
        setTimeout(function() {
            vm.hoge = "プログラムから変更"; // ←これは反映される (1way)
        }, 2000);
    </script>
    

    겉치레


    이 경우 ko.getObservable, 우리는 그것으로 observable 의 에이전트 속성을 처리합니다.
    가까스로 사용getter/setter한 우아한 세상이 망가졌다.
    <input type="text" data-bind="customeValue: _hoge"/>
    <span data-bind="text: hoge"> </span>
    <script>
        function ExampleViewModel() {
            this.hoge = "サンプル";
            ko.track(this);
            // 代理プロパティを設置
            this._hoge = ko.getObservable(this, 'hoge');
        }
        var vm = new ExampleViewModel();
        ko.applyBindings(vm);
    </script>
    

    ES5에 대한 사용자 정의 바인딩 쓰기


    하지만 어렵기 때문에 간단하게 바인딩을 끝까지 쓰려고 하잖아요.별명을 따로 쓰고 싶지 않다observable.그리고 디버깅을 하다가 우연히 이 방법을 발견했어요.Knockout의 코드를 자세히 읽으면 내가 더 일찍 알 것 같아...

    ko.expressionRewriting._twoWayBindings


    이것은 모든 귀속 처리 프로그램에 설정된 표지의 일종으로 다음과 같은 설정true을 통해 실현할 수 있다...
    ko.bindingHandlers['customValue'] = {
        // 省略
    };
    ko.expressionRewriting._twoWayBindings['customValue'] = true;
    
    allBindings() 대상에 하나의 대상_ko_property_writers이 발생한다.

    allBindings()._ko_property_writers


    이름과 같이 속성을 다시 쓰기 위해 수집한 자료setter다.
    allBindings에서 자란 것도 Miso로 다른 귀속 처리 프로그램에서 접근할 수 있습니다.
    이걸로 아래처럼 고쳐 쓰세요.
    ko.bindingHandlers['customValue'] = {
        init: function (element, valueAccessor, allBindings) {
            var suspend = false,
                propWriters = allBindings()['_ko_property_writers'];
    
            function updateModel() {
                suspend = true;
                var value = element.value;
                var modelValue = valueAccessor();
                if (ko.isObservable(modelValue)) {
                    // プロパティが observable ならそのまま書き換え
                    modelValue(value);
                } else if (propWriters && propWriters.customValue) {
                    // ライターがあればそれを使って書き換え
                    propWriters.customValue(value);
                }
            }
    
            element.onchange = updateModel;
    
            ko.computed(function() {
                if (suspend) {
                    suspend = false;
                    return;
                }
                var modelValue = ko.unwrap(valueAccessor());
                element.value = modelValue;
            });
        }
    };
    ko.expressionRewriting._twoWayBindings['customValue'] = true;
    
    이로써 observable뿐만 아니라 단순한 구성원 변수일 경우 View→ViewModel의 1way 귀속, ES5의 업그레이드된 속성일 경우 2way 귀속을 할 수 있다.

    예를 들다


    예를 들어 현재 공개된 사용자 정의 귀속이 이 방법으로 ES5에 대응할 수 있다고 생각되면 참고하십시오.
  • [knockout.js] 체크 상자를 비트 필드에 연결합니다
  • 바인딩과 카드 위치에 "caret binding" 문자열을 삽입합니다.
  • 좋은 웹페이지 즐겨찾기