2016-09-19 5 views
0

부트 스트랩의 모달 기능을 활성화하는 데 도움이되는 녹아웃 사용자 정의 바인딩을 만들었습니다. 그러나 마크 업이 바인딩을 사용할 때 init 메소드가 호출되지 않는 경우가 있습니다.넉 아웃 사용자 정의 바인딩이 가끔

// data-bind="bootstrapModal: {viewModel: {isOpen: ko.observable(false)}, backdrop: 'static'}" 
ko.bindingHandlers.bootstrapModal = { 
    init: function (elem, value) { 
     debugger; // added for debugging 

     var options = ko.utils.unwrapObservable(value()), 
      viewModel = options.viewModel, 
      backdrop = options.backdrop; 

     /* added for debugging */ 
     console.log('Attaching boostrapModal binding to view model.'); 
     console.log(viewModel); 

     debugger; 
     /* end added for debugging */ 

     // do not allow backdrop = true for now; it doesn't sync with the view model 
     if (backdrop === undefined || backdrop === true) { 
      backdrop = 'static'; 
     } 

     if (viewModel.isOpen()) { 
      $(elem).modal({ show: true, backdrop: backdrop }); 
     } 

     viewModel.isOpen.subscribe(function (newVal) { 
      console.log('View model open toggle.'); 
      if (newVal) { 
       $(elem).modal({ show: newVal, backdrop: backdrop }); 
      } else { 
       $(elem).modal('hide'); 
      } 
     }); 
    } 
}; 

이 다음과 같은 마크 업에 사용됩니다

<div class="modal fade" tabindex="-1" role="dialog" data-bind="bootstrapModal: { viewModel: $data, backdrop: 'static' }, with: $data"> 
    <div class="modal-dialog" role="document"> 
    ... rest of modal markup 

$ 데이터는 (다른 것들 사이)을 ISOPEN 관찰 부울 속성 뷰 모델입니다. 우리는 녹아웃 그 때문에 우리의 모든 사용자 정의 바인딩 모두 번들을 만들 ASP.NET MVC의 들러를 사용하는

<script> 
    requirejs(['knockout', 'NavViewModel'], 
     function (ko, nav) { 

      // investigating the binding handlers, bootstrapModal is available 
      console.log(ko.bindingHandlers); 
      debugger; 

      ko.applyBindings(nav.NavViewModel.getInstance(), document.getElementById('navContainer')); 
     }); 
</script> 

: 같은 페이지에서

, 우리는 같은 스크립트에서 가져올 필요로 사용하고 함께 다운로드됩니다.

BundleTable.Bundles.Add(new ScriptBundle("~/scripts/knockout.js") 
      .Include("~/scripts/jquery-1.12.3.min.js") 
      .Include("~/scripts/bootstrap.min.js") 
      .Include("~/scripts/knockout-3.4.0.js") 
      .Include("~/scripts/knockout.customBindings.js")); 

이것은 정확히 어떻게 설정되었지만 실제로는 동일하지 않습니다. '녹아웃'을 요구하면 jockery, bootstrap, knockout 및 사용자 정의 바인딩이 포함 된 번들 knockout.js가 다운로드됩니다.

따라서 바인딩이 발생하기 전에 ko.bindingHandlers에서 바인딩 핸들러를 사용할 수 있습니다. 그러나 사용자 지정 바인딩의 중단 점 (init 함수의 첫 번째 줄)은 항상 적중되지는 않습니다. FF에서는 오류를 거의 보지 못합니다. Chrome에서는 거의 언제나 그렇습니다. 페이지를 계속해서 새로 고치면 두 브라우저 모두에서 작동 상태와 깨진 상태를 확인할 수 있습니다.

답변

0

스크립트가 영향을주는 마크 업 아래에 있더라도 실제로는 실제로 바인딩을 적용 할 수 있습니다. applyBindings 호출을 DOM 준비 콜백으로 이동하면 문제가 해결되었습니다.

<script> 
    requirejs(['jquery', 'knockout', 'NavViewModel'], 
     function ($, ko, nav) { 

      $(function() { 
       ko.applyBindings(nav.NavViewModel.getInstance(), document.getElementById('navContainer')); 
      }); 
     }); 
</script> 
관련 문제