2016-01-09 3 views
9

Ho una direttiva angolare che sto usando per posizionare un modulo di pulsante. Il modello è nascosto fino a quando l'utente non ha bisogno di vederlo. È un modello semplice che funziona da solo, ma quando lo combino nella forma più grande il modello non appare.Modello angolare non visualizzato con ng-hide

Ecco la direttiva:

.directive('buttonToggle', function() { 
       return { 
        restrict: 'A', 
        scope: { 
         myBtnArr: "=" 
        }, 
        template: '<button ng-click="click()">{{ myBtnTxt[myBtnArr] }}</button>', 
        link: function(scope) { 
         scope.myBtnTxt = ["AND", "OR", "NOT"]; 
         scope.click = function() { 
          scope.myBtnArr = (scope.myBtnArr < 2 ? scope.myBtnArr + 1 : 0); 
         } 
        } 
       }; 
      }); 

Poi il codice HTML che funziona:

<div button-toggle my-btn-arr=0></div> 

E il frammento di codice HTML che non funziona:

<tr ng-show="rowsShown >= 2"><td>Search by:</td><td><div button-toggle my-btn-arr=0></div><select ng-model="selection2" ng-options="option.text for option in options"></select><input type="text" size="20" ng-model="queryF2"><ng-md-icon icon="add_circle_outline" style="fill:#a9a9a9" ng-click="addSearchField();"></ng-md-icon> <ng-md-icon icon="remove_circle_outline" style="fill:#a9a9a9" ng-click="removeSearchField();"></ng-md-icon></td></tr> 

Quando eseguo questo html nel partial più grande (che è controllato da un controller non correlato al modello) ottengo questo errore:

Error: [$compile:nonassign] Expression '0' used with directive 'buttonToggle' is non-assignable! 

Quindi racchiudere la funzione di modello in ambito. $ Applicare? No. Quando faccio che ...

link: function(scope) { 
      scope.myBtnTxt = ["AND", "OR", "NOT"]; 
      scope.click = function() { 
       scope.$apply (function() { 
        scope.myBtnArr = (scope.myBtnArr < 2 ? scope.myBtnArr + 1 : 0); 
       }) 
      } 
     } 

ottengo questo errore:

Error: [$rootScope:inprog] $apply already in progress 

Quindi è ovviamente un problema con avvolgimento in modo non corretto il campo di applicazione, ma non è sicuro come risolvere il problema. qualche idea?

risposta

7

Sembra che non si desidera creare un binding per my-btn-arr a due vie . Se si desidera semplicemente passare i dati alla direttiva anziché eseguire il binding a una variabile esistente, leggere dall'argomento attributo di link.

.directive('buttonToggle', function() { 
    return { 
     restrict: 'A', 
     scope: {}, 
     template: '<button ng-click="click()">{{ myBtnTxt[myBtnArr] }</button>', 
     link: function(scope, elem, attr) { 
     scope.myBtnArr = attr.myBtnArr; 
     scope.myBtnTxt = ["AND", "OR", "NOT"]; 
     scope.click = function() { 
      scope.myBtnArr = (scope.myBtnArr < 2 ? scope.myBtnArr + 1 : 0); 
     } 
     } 
    } 
    }); 

Se si desidera anche la possibilità di passare una variabile come l'uso di input $parse.

// This won't work with an isolated scope, inherit from parent scope instead 
scope : true, 
link: function(scope, elem, attr) { 
    // this will evaluate the expression against the scope 
    scope.myBtnArr = $parse(attr.myBtnArr)(scope); 
} 

Ora è possibile utilizzare la direttiva come

<div button-toggle my-btn-arr="0"></div> 
<div button-toggle my-btn-arr="view.myValue"></div> 

Se davvero si vuole utilizzare un modo vincolante a due, deve essere possibile scrivere valori di nuovo nel percorso definito con l'espressione my-btn-arr.Quindi, se si utilizza scope: { myBtnArr: "=" } è necessario utilizzare la direttiva con un'espressione scrivibile come questo:

<div button-toggle my-btn-arr="view.myValue"></div> 
<!-- "0" is not assignable--> 
<div button-toggle my-btn-arr="0"></div> 

Esempi: http://jsfiddle.net/Lw7ckt9x/1/

+0

Questa era la mia ipotesi su dove potrei aver sbagliato ... fammi provare questo e tornare da te. –

+0

Ha funzionato! E hai ragione, avevo solo bisogno di un legame unidirezionale. Grazie! –

3

Invece di utilizzare la funzione di collegamento, provare a fare la stessa cosa con la funzione di controllo. La funzione di collegamento è necessaria quando si esegue qualsiasi manipolazione DOM per la funzionalità richiesta che il controller dovrebbe essere sufficiente.

+0

Proprio così ho capito, sono abbastanza sicuro che sto facendo manipolazione del DOM. Quando l'utente fa clic su quel pulsante si sposta tra tre stati diversi. Ho anche bisogno che il numero dei pulsanti aggiunti da questo modello sia flessibile, in modo che l'utente possa aggiungerne quanti ne ha bisogno. –

+0

All'interno della funzione click stai semplicemente impostando uno stato su myBtnArr, il DOM viene modificato da Angular. Se stai facendo qualche manipolazione DOM tradizionale come trovare il controllo e impostare le sue cose come questo dovrebbe essere fatto nella funzione Link. Qui il testo del pulsante viene modificato a causa dell'associazione dati bidirezionale supportata da Angular. –

2

Guarda questo errore su ngdocs.

si utilizza questo:

<div button-toggle my-btn-arr=0></div> 

ma 0 non è cedibile. Significa che non si può fare 0 = 1;

Devi passare una variabile con valore 0 invece del semplice 0 Ti piace questa:

<div button-toggle my-btn-arr="obj.myvar"></div>