2016-09-19 4 views
0

Ich habe eine Knockout-Custom-Bindung erstellt, die die modale Funktionalität des Bootstrap aktiviert. Manchmal wird die init-Methode jedoch nicht aufgerufen, wenn das Markup die Bindung verwendet.Knockout Custom Binding startet nicht manchmal

// 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'); 
      } 
     }); 
    } 
}; 

Dieser mit dem folgenden Markup:

<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 

$ data ist eine Ansicht Modell mit einer isOpen beobachtbaren boolean Eigenschaft (unter anderem).

In der gleichen Seite, verwenden wir wie in den Skripten bringen benötigen:

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

Wir bundler die ASP.NET MVC verwenden sowohl ein Bündel mit Knockout zu schaffen und alle unsere kundenspezifischen Bindungen, so dass Sie werden zusammen heruntergeladen.

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")); 

Dies ist nicht genau, wie es wirklich Setup ist, aber effektiv das Gleiche. Wenn Sie 'knockout' benötigen, laden Sie das Bundle knockout.js herunter, das jquery, bootstrap, knockout und die benutzerdefinierten Bindungen enthält.

Bevor also Bindungen auftreten, ist der Bindungshandler in ko.bindingHandlers verfügbar. Der Haltepunkt in den benutzerdefinierten Bindungen (erste Zeile der Init-Funktion) wird jedoch nicht immer getroffen. In FF beobachte ich den Fehler selten. In Chrome ist es fast immer. Wenn Sie die Seite immer wieder aktualisieren, werden in beiden Browsern schließlich sowohl der Arbeitsstatus als auch der Fehlerstatus angezeigt.

Antwort

0

Obwohl sich das Skript unterhalb des Markups befindet, auf das es sich auswirkt, würde es die Bindung nur manchmal tatsächlich anwenden. Durch das Verschieben des applyBindings-Aufrufs in den DOM-fähigen Rückruf wurde das Problem behoben.

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

      $(function() { 
       ko.applyBindings(nav.NavViewModel.getInstance(), document.getElementById('navContainer')); 
      }); 
     }); 
</script> 
Verwandte Themen