2013-04-16 8 views
5

Dai un'occhiata al seguente esempio di codice HTML. È un semplice collegamento KO foreach e un pulsante per aggiungere un nuovo elemento allo observableArray. L'aggiunta funziona correttamente e viene visualizzato il nuovo elemento. Tuttavia, il metodo afterRender non viene mai chiamato, non dopo il bind iniziale e non dopo l'aggiunta (e il rendering) di un nuovo elemento. Perché?Perché afterRender non viene mai chiamato?

Fiddle:http://jsfiddle.net/CQNm6

HTML

<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <meta charset="utf-8" /> 
     <title></title> 
     <script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script> 
    </head> 
    <body> 
     <div data-bind="foreach: data.things, afterRender: afterRenderTest"> 
      <h1 data-bind="text: name"></h1> 
     </div> 
     <a href="JavaScript:void(0);" onclick="data.things.push({ name: ko.observable('New Thing') });">Add New Thing</a> 

     <script type="text/javascript"> 
      var Thing = (function() 
      { 
       function Thing(p_name) 
       { 
        this.name = ko.observable(p_name); 
       } 

       return Thing; 
      })(); 
      var data = 
      { 
       things: ko.observableArray(
       [ 
        new Thing("Thing One"), 
        new Thing("Thing Two"), 
        new Thing("Thing Three") 
       ]) 
      }; 

      function afterRenderTest(elements) 
      { 
       alert("Rendered " + elements.length + " elements."); 
      } 

      ko.applyBindings(); 
     </script> 
    </body> 
</html> 

risposta

12

tua sintassi è sbagliata, perché vincolante foreach prendere un array o un oggetto in cui si specificano le ulteriori eventi, argomenti.

Dal documentaiton:

passare la matrice che si desidera iterare. Il binding produrrà una sezione di markup per ogni voce.

In alternativa, passare un oggetto JavaScript letterale con una proprietà denominata data che è l'array che si desidera ripetere. L'oggetto letterale può anche avere altre proprietà, come afterAdd o includeDestroyed ...

Quindi è necessario scrivere:

<div data-bind="foreach: { data: data.things, afterRender: afterRenderTest }"> 
    <h1 data-bind="text: name"></h1> 
</div> 

Demo JSFiddle.

+0

sciocco me, grazie! –