Domanda

Ho un problema molto specifico con una direttiva che inizia con determinate lettere (t, u, v, w, y, z). La direttiva viene utilizzata su un elemento select e sta guardando le modifiche generanodicetagcode.

Quando ngOptions è popolato con i dati da una richiesta Ajax e il nome della direttiva inizia con una determinata lettera, ad es. w, il secondo orologio si incrementa la callback prima che siano state create le opzioni selezionate. Se il nome della direttiva inizia con una lettera diversa (A, K, M, N) il secondo ricircolo di callback degli incendi dopo che le opzioni sono state create.

qui è un campione con più direttive che iniziano con varie lettere. Apri la tua console per vedere il problema.

<select w-foo ng-model="bar" ng-options="o.name for o in options"></select>
.
app.controller("test", function ($scope, $timeout) {

    // Emulate ajaxed options
    $timeout(function () {
        $scope.options = [{
            name: "aaa",
            id: 1
        }, {
            name: "bbb",
            id: 2
        }, {
            name: "ccc",
            id: 3
        }];
    }, 500);

});

app.directive("wFoo", function () {
    return {
        require: 'ngModel',
        link: function (scope, element, attrs, ngModel) {
            scope.$watch(attrs.ngOptions.replace(/.*in /, ""), function () {
                console.log("w-foo ngOptions changed", element.html());
            });
        }
    };
});
.

Nel codice sopra, ngOptions conterrà un singolo generacolo di generazione vuoto nella prima richiamata (il digest iniziale) e conterrà anche un singolo element.html() vuoto nel secondo digest (quando l'Ajax è completo).

Da dove viene questo comportamento?

È stato utile?

Soluzione

Ci sono tre meccanismi qui coinvolti per spiegare questo comportamento:

    .
  1. Gli osservatori vengono eseguiti nella stesso ordine che sono registrati ( Vedi il codice del metodo $watch () ).

  2. Le funzioni di post-link sono eseguite nell'ordine inverso della loro priorità ( Vedere la documentazione per la proprietà priority ).

  3. Le direttive con la stessa priorità vengono eseguite in un ordine indefinito. La priorità predefinita è 0, quindi tutte le direttive personalizzate qui hanno questa priorità. Dal momento che select Direttiva come anche una priorità del 0, l'ordine di esecuzione è indefinito .

    Come si nota, "indefinito" è un po 'eccessivo, e in realtà l'ordine di esecuzione è l'ordine alfabetico ( Vedi il codice $compile ): Direttive con un nome all'inizio del dizionario hanno una priorità più alta. Ma, nella mia umile opinione, poiché questo non è esplicitamente detto nella documentazione, non puoi fare affidamento su questo comportamento .

  4. Per riassumere, ecco alcuni casi di utilizzo. Ogni direttiva registra un osservatore.

      Name  |  Priority  | Watcher order
    --------+------------+--------------
    A       | 100        | 3rd
    B       | 0          | 2nd
    C       | none (= 0) | 1st
    
    .

    Quindi, per risolvere il problema è semplice:

      .
    • Se si desidera eseguire l'osservatore delle direttive personalizzate dopo The select One, conferisci alla tua direttiva una priorità superiore a 0.
    • Se si desidera eseguire l'osservatore delle direttive personalizzate Prima The select One, Bene ... Poiché sono proibiti la priorità negativa, non è possibile farlo in modo affidabile.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top