2015-02-07 19 views
5

Sto cercando di fare in modo che la fabbrica Thing effettui una richiesta HTTP e sia in grado di utilizzare la risposta nel mio controller.Perché devo usare angular.copy nella mia fabbrica?

  1. Nella mia fabbrica devo fare angular.copy(data, arr). Semplicemente facendo arr = data non funziona. Perchè è questo? angular.copy() solo una) cancella tutto, dalla arr e b) scorre data e assegna roba da arr. L'unica differenza tra questo e arr = data è che arr punti a data piuttosto che una nuova copia di data. Perché dovrebbe essere così importante? E perché non fa arr = data.slice(0) lavoro (da quanto ho capito, è praticamente la stessa di angular.copy)?

  2. Qual è il modo migliore per realizzare il mio obiettivo? (Utilizzare la fabbrica correttamente)

main.html

<div class="container"> 

<div class="page-header"> 
    <h1>Test App</h1> 
</div> 

<ul> 
    <li ng-repeat="thing in things">{{thing.name}}</li> 
</ul> 

</div> 

main.controller.js

+0

angular.copy lavora per gli oggetti o array, sono dati un oggetto per caso? A proposito, dovresti fare uso di sollevamento ed estrarre le tue funzioni anon in funzioni con nome e passare semplicemente il nome della funzione al metodo factory e controller. Rende molto più facile capire i componenti di un modulo. – Robert

+0

'data' è una matrice di oggetti. –

+1

Funziona perché arr (array) è un riferimento ed è necessario conservare il riferimento affinché i bind di ambito funzionino.Altrimenti, stai semplicemente sovrascrivendo arr con un nuovo riferimento - che è completamente diverso dal riferimento originariamente legato all'ambito. – pixelbits

risposta

7

Il tuo problema non è legato al angolare, ma a Javascript.

var arr = [] // arr is a pointer to an empty array 
var things = arr // things is a pointer to the same empty array 
arr = data // now arr points to data, but things still points to the empty array 

È possibile convincersi di quel eseguendo il seguente codice:

var a = [1]; 
var b = a; 
a = [2]; 
// Now if you console.log a and b, a === [2] and b === [1] 

Tuttavia, se si manipola la proprietà di un oggetto

var a = { data: 1 } 
var b = a; 
a.data = 2; 
// Now a.data and b.data are the same: 2 
a = { data: 3 }; 
// Here we changed a, not its property, so a and b are not the same anymore 
// a.data === 3 but b.data === 2 

Se si capisce questo, ci sono molti modi per risolvere il problema, come ad esempio:

angular.module('testApp') 
    .factory('Thing', function($http) { 
    var obj = {}; 
    return { 
    things: obj, 
    get: function() { 
     $http.get('/api/things').success(function(data) { 
     obj.data = data; 
     }); 
    } 
    }; 
}) 

E nel codice HTML utilizzare things.data.

O se non si vuole utilizzare una proprietà dell'oggetto, ma direttamente la matrice, invece di sostituire il puntatore è necessario aggiornare solo il contenuto della matrice (in modo arr ancora punti a quello stesso array):

angular.module('testApp') 
    .factory('Thing', function($http) { 
    var arr= []; 
    return { 
    things: arr, 
    get: function() { 
     $http.get('/api/things').success(function(data) { 
     for (var i in data) { 
      arr[i] = data[i]; 
     } 
     }); 
    } 
    }; 
}) 
+0

Ah mi sento così stupido a ben vedere. Grazie! –

0

Questo accade perché si imposta arr in una nuova istanza di una matrice invece di utilizzare quella corrente. Ecco un'analogia con quello che stai facendo:

var foo = function() { 
    this.test = 'hello'; 
    console.log(this.test); 
}; 

foo = function() { 
    this.test = 'other'; 
    console.log(this.test); 
}; 

console.log(foo()); // outputs other 

angular.copy fa invece qualcosa di simile:

// foreach item in the source (in this case data) 
arr.push({ 
    my: "value" 
}); 
Problemi correlati