2013-03-30 14 views
16

Ho una direttiva all'interno di un ripetitore ng che dovrebbe impostare una proprietà scope. Si prega di consultare il violino qui: http://jsfiddle.net/paos/CSbRB/Come impostare il valore della proprietà dell'oggetto del controller angolare dalla direttiva nello scope figlio

Il problema è che la proprietà campo di applicazione è dato come un valore di attributo come questo:

<button ng-update1="inputdata.title">click me</button> 

La direttiva dovrebbe impostare la proprietà ambito inputdata.title a qualche stringa . Questo non funziona:

app.directive('ngUpdate1', function() { 
    return function(scope, element, attrs) { 
     element.bind('click', function() { 
      scope.$apply(function() { 
       scope[ attrs.ngUpdate1 ] = "Button 1"; 
      }); 
     }); 
    }; 
}); 

Tuttavia, assegnando direttamente funziona:

scope["inputdata"]["title"] = "Button 1"; 

Può cortesemente dirmi come posso impostare una proprietà ambito con. notazione nel suo nome da una direttiva?

PS: Il motivo per cui il violino sta utilizzando un ripetitore è perché rende le direttive in ambito figlio. Quando si trovano in un ambito figlio, non è possibile scrivere sulle proprietà dell'ambito che sono primitive. Ecco perché ho bisogno di una proprietà dell'oggetto con "." nel nome. Vedere la lunga spiegazione qui: What are the nuances of scope prototypal/prototypical inheritance in AngularJS?

Grazie

+0

Una soluzione poco elegante sarebbe quella di utilizzare la forma di stringa di '$ apply', ad esempio:.' Ambito $ applicare (attrs.ngUpdate1 + '=' + '"Button 1"'); '. –

+0

@Josh, nel caso in cui non hai visto la mia risposta, l'elegante soluzione è usare '$ parse'. –

risposta

35

$parse risolverà il tuo problema.

<button ng-update1="inputdata.title"> 
app.directive('ngUpdate1', function($parse) { 
    return function(scope, element, attrs) { 
     var model = $parse(attrs.ngUpdate1); 
     console.log(model(scope)); // logs "test" 
     element.bind('click', function() { 
      model.assign(scope, "Button 1"); 
      scope.$apply(); 
     }); 
    }; 
}); 

Fiddle

Ogni volta che una direttiva non usa un ambito isolato e si specifica una proprietà ambito utilizzando un attributo, e si desidera modificare il valore, usare $parse.

Se non è necessario modificare il valore, è possibile utilizzare $eval invece:

console.log(scope.$eval(attrs.ngUpdate1)); 
+0

Proprio sopra. Grazie! – user681814

+0

Puoi fare la stessa cosa usando ng-model come l'attributo html invece di uno personalizzato assumendo che il tuo elemento html sia una direttiva e hai il codice che hai presentato qui in un link: function? – sonicblis

+0

@sonicblis, ti suggerisco di postare una nuova domanda con un violino, dal momento che stai chiedendo di uno scenario molto diverso. La risposta dipenderà anche dal tipo di ambito utilizzato dalla direttiva. Questo potrebbe aiutare: http://stackoverflow.com/questions/11896732/ngmodel-and-component-with-isolated-scope –

2

Non so cosa obiettivo generale è, ma è un modo per creare 2 attributi, uno per l'oggetto di destinazione e l'altra per la proprietà di tale oggetto:

<button ng-update1 obj="inputdata" prop="title"> 
app.directive('ngUpdate1', function() { 
    return function(scope, element, attrs) { 
     element.bind('click', function() { 
      scope.$apply(function() {     
       scope[ attrs.obj ][attrs.prop] = "Button 1";    

      }); 
     }); 
    }; 
}); 

DEMO: http://jsfiddle.net/CSbRB/9/

alternativa utilizzando il formato esistente si potrebbe split() val ue del vostro attuale ng-update1 attributo e l'uso di matrice risultato per oggetto e proprietà in notazione

element.bind('click', function() { 
      var target=attrs.ngUpdate1.split('.'); 
      scope.$apply(function() {     
       scope[ target[0] ][target[1]] = "Button 1";    

      }); 
     }); 

DEMO con entrambi gli approcci: http://jsfiddle.net/CSbRB/10/

Un approccio più in cui si crea un ambito isolato in direttiva e che possono passare nel riferimento a inputdata oggetto e tirare nome della proprietà da dell'attributo (stesso markup come seconda versione):

app.directive('ngUpdate3', function() { 
    return { 
     scope: { 
      targetObject: '=obj' 
     }, 
     link: function (scope, element, attrs) { 
      element.bind('click', function() { 
       scope.$apply(function() { 
        scope.targetObject[attrs.prop]='Button 3'; 

       }); 
      }); 
     } 
    } 
}); 

http://jsfiddle.net/CSbRB/11/

+0

Invece di due attributi o 'split()', usare invece '$ parse' (vedere la mia risposta). Inoltre, con un ambito isolato, è possibile associare direttamente la proprietà dell'oggetto se si desidera/necessario: '", quindi nella direttiva: 'scope: { model: '='} '. [Fiddle] (http://jsfiddle.net/mrajcok/3nb8D/) –

+0

@MarkRajcok grazie .. stava cercando di legare alla proprietà in ambito isolato in precedenza e non sono sicuro del motivo per cui non funzionava .. i documenti per $ parse sono terribili ... i tuoi commenti aiutano. Sembra che ci dovrebbero essere approcci più intuitivi rispetto alla necessità di usare '$ parse' quindi' assign' – charlietfl

+0

Ho avuto problemi di associazione a una proprietà in un ambito isolato anche nel tuo violino. Penso che il problema sia la versione più vecchia di Angular (1.0.0) nel tuo violino. –

Problemi correlati