2013-06-01 13 views
24

Fiddle: http://jsfiddle.net/LkqTU/9399/Przybornik Bootstrapa nie działa z wiązaniami typu knockout? (W skrzypcach)

Kod:

var ViewModel = function (first, last) { 
    var self = this; 
    self.showIcon = ko.observable(false); 
    self.triggerIcon = function() { 
     self.showIcon(true); 
    }; 
}; 
$('.card-delete-button').tooltip({ 
    'placement': 'top', 
     'title': 'Text' 
}); 
ko.applyBindings(new ViewModel("Planet", "Earth")); 

Z jakiegoś powodu etykietka nie jest wyświetlany na przycisku '.card-delete-'. Myślę, że to dlatego, że ten element DOM jest niedostępny, dopóki nie zostanie uruchomiona funkcja triggerIcon. Ale w aplikacji, muszę powiązać te podpowiedzi z wieloma różnymi elementami i wolałbym to zrobić raz, w jednym miejscu, zamiast przyklejać wiązanie do funkcji triggerIcon. Jak można to osiągnąć?

Odpowiedz

56

Najlepszym rozwiązaniem w takiej sytuacji jest utworzenie niestandardowego powiązania, za pomocą którego można umieszczać podpowiedzi w dowolnym miejscu znaczników.

Oto jeden realizacja podpowiedzi oprawa:

ko.bindingHandlers.tooltip = { 
    init: function(element, valueAccessor) { 
     var local = ko.utils.unwrapObservable(valueAccessor()), 
      options = {}; 

     ko.utils.extend(options, ko.bindingHandlers.tooltip.options); 
     ko.utils.extend(options, local); 

     $(element).tooltip(options); 

     ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
      $(element).tooltip("destroy"); 
     }); 
    }, 
    options: { 
     placement: "right", 
     trigger: "click" 
    } 
}; 

byłoby wtedy użyć tego wiązania na swojej stronie jak:

<input data-bind="value: name, tooltip: { title: help, trigger: 'hover' }" /> 

Można ustawić opcje globalnie, a następnie zastąpić je cokolwiek przejść do wiązania.

Po przejściu do scenariuszy i scenariuszy sterowania przepływem, używanie niestandardowego wiązania naprawdę pomaga, ponieważ automatycznie zostanie zainicjowane (i wyczyszczone) we właściwym czasie, bez konieczności ręcznego sprawdzania, kiedy należy wywoływać kod.

Oto przykład: http://jsfiddle.net/rniemeyer/BF5yW/

+0

Wow. Ale fajnie. Dziękuję :) – RobVious

+3

@RP Niemeyer, jesteś bestią z knockout.js. Wiele twoich odpowiedzi na Stackoverflow było bardzo pomocne! Dzięki! –

7

Uzupełnienie do @RP odpowiedź Niemeyera ...

Na github znajduje się mały projekt o nazwie Knockout-Bootstrap dokonywania „bogaty dwie sposób interakcji z Bootstrap i Knockout wiązań”.

Poniżej znajduje się widelec twojego skrzypka, który zawiera Knockout-Bootstrap.

http://jsfiddle.net/qZkXP/

<div class='liveExample' data-bind="event: {mouseover: triggerIcon}"> 
    <!-- ko if: showIcon --> 
    <a class="card-delete-button" 
     data-bind="tooltip: {title: 'Another tooltip', placement: 'right'}"> 
      <i class="icon-trash"></i> 
    </a> 
    <!-- /ko --> 
</div> 
+0

To niesamowite, dzięki dla Ciebie – RobVious

4

ja również napotkał pewne problemy dotyczące wiązania z nokautem i odpowiedzi oferowanych przez RP Niemeyer podpowiedź mi pomógł. Ale wtedy, gdy próbowałem powiązać z funkcją, która zwraca obiekt opcji etykiety narzędzia, to nie było wywoływane (zostało wywołane tylko raz). Tak więc nie działało, gdy próbowałem dynamicznie zmieniać tytuł etykiety narzędziowej, w oparciu o zmapowane klasy css. Tak więc, rozwiązanie znalazłem to:

ko.bindingHandlers["tooltip"] = { 
'init': function (element, valueAccessor) { 
    var local = ko.utils.unwrapObservable(valueAccessor()); 
    var options = {}; 

    ko.utils.extend(options, ko.bindingHandlers.tooltip.options); 
    ko.utils.extend(options, local); 

    $(element).tooltip(options); 

    ko.utils.domNodeDisposal.addDisposeCallback(element, function() { 
     $(element).tooltip("destroy"); 
    }); 
}, 
'update': function (element, valueAccessor) { 
    var local = ko.utils.unwrapObservable(valueAccessor()); 
    var options = {}; 

    ko.utils.extend(options, ko.bindingHandlers.tooltip.options); 
    ko.utils.extend(options, local); 

    $(element).data("bs.tooltip").options.title = options.title; 
}, 
options: { 
    placement: "top", 
    trigger: "click" 
}}; 

Chciałem zrobić tę uwagę tutaj, bo myślę, że warto byłoby w tych przypadkach, gdy tytuł etykiecie musi być zmieniane dynamicznie.

Powiązane problemy