Sök…


Syntax

  • <!-- ko if:myObservable --><!-- /ko -->
  • <i data-bind="if:myObservable"></i>

Anmärkningar

Vad en bindning är

I huvudsak är en bindning eller en databindning ett sätt att länka dina ViewModels till dina vyer (mallar) och vice versa. KnockoutJS använder tvåvägsdatabindning, vilket innebär att ändringar i din ViewModel påverkar vyn och ändringar av din View kan påverka ViewModel.

Under huven (kort översikt)

Bindningar är bara plugins (skript) som låter dig lösa en viss uppgift. Denna uppgift ändrar ofta än inte markering (html) enligt din ViewModel.

Till exempel tillåter en text att du kan visa text och dynamiskt ändra den när din ViewModel ändras.

KnockoutJS kommer med många kraftfulla bindningar och låter dig förlänga den med dina egna anpassade bindningar.

Och viktigast av allt är bindningar inte magiska, de fungerar enligt en uppsättning regler och när du är osäker på vad en bindning gör, vilka parametrar den tar eller när den kommer att uppdatera vyn kan du hänvisa till källkoden för bindningen.

Tänk på följande exempel på en anpassad bindning:

ko.bindingHandlers.debug = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ko.computed(function () {
            var value = ko.unwrap(valueAccessor());
    
            console.log({
                value: value,
                viewModel: viewModel,
                bindingContext: bindingContext
            });
        }, null, { disposeWhenNodeIsRemoved: element });
    }
};
  1. En bindning har ett namn - debug så att du kan använda följande:

data-bind="debug: 'foo'"

  1. init metoden kallas en gång när bindningen initieras. Resten av uppdateringarna hanteras av en anonym dator som kasseras när element tas bort.
  2. Bindningen skriver ut för att trösta flera saker: det överförda värdet i vårt exempel detta värde är foo (detta värde kan också observeras eftersom ko.unwrap metoden används för att läsa det), den aktuella viewModel och bindingContext.
  3. När det överförda värdet ändras kommer bindningen att skriva ut uppdaterad information till konsolen.
  4. Denna bindning kan inte användas med virtuella element (i html-kommentarer), bara på riktiga element, eftersom ko.virtualElements.allowedBindings.debug flaggan inte är inställd på true.

När du ska använda parenteser

Utan några extra plugins kommer KnockoutJS endast att ha live View-uppdateringar för egenskaper på ViewModel som är observerbara (regelbunden observable , men också computed , pureComputed , observableArray , etc). En observerbar skulle skapas så här:

var vm = { name: ko.observable("John") };

I detta fall är vm.name en funktion med två separata "lägen":

  1. Getter: vm.name() kommer utan argument att få det aktuella värdet;
  2. Setter: vm.name("Johnnyboy") , med ett argument, sätter ett nytt värde.

I de inbyggda databindningarna kan du alltid använda getterformuläret, och ibland kan du faktiskt utelämna parenteserna, och bindningen "effektivt" lägger till dem åt dig. Så dessa är likvärdiga:

<p data-bind="text: name"></p> ... will work
<p data-bind="text: name()"></p> ... works too

Men detta kommer att misslyckas:

<p data-bind="text: 'Hello, ' + name + '!'"></p> ... FAILS!

Eftersom så fort du vill "göra" något innan du överför ett värde till en databindning, inklusive värdesjämförelser, måste du "få" värdena för alla observerbara objekt, t.ex.:

<p data-bind="text: 'Hello, ' + name() + '!'"></p> ... works

Se även denna fråga & frågor för mer information.

Om / om inte

Du kan använda if bindningen för att avgöra om barnelementen i noden ska skapas eller inte.

<div class="product-info">
    <h2>  Product1  </h2>
    <img src="../products/product1.jpg"/>
    <span data-bind="if:featured">
        <span class="featured"></span>
    </span>
    <span data-bind="ifnot:inStock">
        <span class="out-of-stock"></span>
    </span>
</div>
     
<script>
    ko.applyBindings({
        product: {
            featured: ko.observable(true),
            inStock: ko.observable(false)
        }
    });
</script>

Det omvända av if bindningen är ifnot

<div data-bind="ifnot: someProperty">...</div>

är ekvivalent med

<div data-bind="if: !someProperty()">...</div>

Ibland kommer du inte att kontrollera förekomsten av element utan att behöva skapa en behållare (vanligtvis för <li> element i en <ul> eller <option> -element inuti ett <select> )

Knockout möjliggör detta med behållarlöst kontrollflödessyntax baserat på kommentar taggar så:

<select>
  <option value="0">fixed option</option>
<!-- ko if: featured-->
  <option value="1">featured option</option>
<!-- /ko -->
</select>

För varje

Liknar repeater som används på andra språk. Denna bindning gör att du kan replikera ett block med html för varje objekt i en matris.

<div data-bind="foreach:contacts">
    <div class="contact">
        <h2 data-bind="text:name">
        <p data-bind="text:info">
    </div>
</div>
 
<script type="text/javascript">
    var contactViewModel = function (data) {
        this.name = ko.observable(data.name);
        this.info = ko.observable(data.info);
    };

    ko.applyBindings({
        contacts: [
            new contactViewModel({name:'Erik', info:'[email protected]'}),
            new contactViewModel({name:'Audrey', info:'[email protected]'})
        ]
    });
</script>

Lägg märke till att när vi går igenom vårt sammanhang blir objektet i matrisen, i detta fall en instans av contactViewModel . Inom en foreach vi också tillgång till

  • $parent - visningsmodellen som skapade denna bindning
  • $root - root view-modellen (kan också vara överordnad)
  • $data - uppgifterna i detta index i matrisen
  • $index - det (observerbara) nollbaserade indexet för den återgivna artikeln

Med

Den with bindande binder HTML i den bundna noden till ett separat sammanhang:

<div data-bind="with: subViewModel">
  <p data-bind="text: title"></p>
</div>

Den with bindning kan också användas utan ett behållarelement där ett behållarelement kanske inte är lämpligt.

<!-- ko with: subViewModel -->
  <p data-bind="text: title"></p>
<!-- /ko -->
var vm = {
  subViewModel: ko.observable()
};

// Doesn't throw an error on the `text: title`; the `<p>` element 
// isn't bound to any context (and even removed from the DOM)
ko.applyBindings(vm);

// Includes the `<p>` element and binds it to our new object
vm.subViewModel({ title: "SubViewModel" });

Den with bindning har många likheter med template eller foreach .

Synlig

Den visible bindningen döljer ett element genom att använda style="display: none;" till det när bindningen utvärderar som falsey.

<input type="text" data-bind="textInput: name"> <span class="error" data-bind="visible: isInvalid">Required!</span>

ko.applyBindings(new ViewModel());

function ViewModel(){
    var vm = this;
  vm.name = ko.observable("test");
  vm.isInvalid = ko.computed(function() {
      return vm.name().length == 0;
  });
}

jsFiddle



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow