2013-07-02 10 views
7

Sono molto nuovo per Angular, quindi spero di saperne abbastanza per chiedere che cosa sembra una domanda ragionevole sul design.Pattern Active Record o Data Mapper per Angularjs?

Sto analizzando alcuni dati tramite Angolare e sto usando $ risorse. Prima di inserire Angular nel progetto, ho creato una funzione di creazione di grafici per la creazione di oggetti grafici da dati json campione che ho appena incollato nella vista.

Ora che sto usando angolare, è forte la tentazione di mettere le funzioni di creazione di grafici nella risorsa 'Grafico', Record stile attivo, in modo che ho questa una cosa che può disegnare, salvare, aggiornare, ecc

Mentre il vantaggio di quel modello è la semplicità, lo svantaggio è l'accoppiamento della persistenza con il comportamento. Ad esempio, sarebbe piuttosto imbarazzante se volessi salvare le impostazioni del grafico nella memoria locale.

Dopo essere stato morso da AR già abbastanza volte nella mia carriera, voglio andare con DM lasciando il mio oggetto grafico così com'è e avendo il controller passare i dati dalla risorsa alla mia tabella.

Tuttavia! La mia confusa comprensione dell'iniezione di dipendenza di angularjs suggerisce che potrei essere in grado di creare una risorsa o qualcosa di simile che possa accettare un'interfaccia di persistenza comune - la parola giusta è un "ambito"? strategia

Esempio AR:

App.factory('Chart', [ 
    '$resource', function($resource) { 
    var chart = $resource('/api/charts/:id', { 
     id: '@id' 
    }); 

    chart.draw = function() { ... } 

    return chart 
    } 
]); 

App.controller('ChartsCtrl', [ 
    '$scope', 'Chart', function($scope, Chart) { 
    $scope.charts = Chart.query(function() { 
     $.each($scope.charts, function(i, c) { c.draw() }) 
    }) 
    } 
]) 

Esempio strategia DM:

App.chart = function(resource) { 
    return { draw: function() { ... } } 
} 

App.factory('ChartResource', [ 
    '$resource', function($resource) { 
    return $resource('/api/charts/:id', { 
     id: '@id' 
    }) 
    } 
]) 

App.controller('ChartsCtrl', [ 
    '$scope', 'ChartResource', function($scope, ChartResource) { 
    $scope.charts = $.map(ChartResource.query(), function(i, resource) { 
     chart = App.chart(resource) 
     chart.draw() 
     return chart 
    } 
    } 
]) 

Penso che ci sia una terza via, però, che non vedo perché non ho ben Grok come sfruttare il DI.

In altre parole, qual è il modo AngularJS per creare un oggetto con strategie di persistenza scambiabili?

+0

questo dovrebbe essere più visibile in quanto è un problema comune quando si progettano le applicazioni gravi AngularJS. – Danita

+0

Sto pensando che ChartResource dipenda da Chart e aggiunga un callback alla chiamata che prenderebbe i dati ricevuti e creerebbe una nuova istanza Chart.In questo modo un controller può chiamare ChartResource o LocalStorageChart (o un servizio che chiama LocalStorageChart e utilizza ChartResource come fallback \ quando il tempo scade per invalidare). Cosa ne pensi? – haimlit

risposta

3

La strategia DataMapper è in realtà già una forma di Iniezione delle dipendenze. Si sta trasferendo l'implementazione di persistenza desiderata al costruttore di Chart e si può passare a uno diverso in base al per- new. Il modo non-DI significherebbe codificare in modo rigido l'implementazione della persistenza, come nell'esempio in stile ActiveRecord.

DataMapper non è DI nel senso specifico Angular.JS del termine. Il DI di Angular in realtà non ti consente di scambiare le implementazioni in fase di esecuzione. Tuttavia, per ottenere questo è possibile utilizzare il modulo ufficiale ngMock. ngMock dovrebbe essere usato per i test, quindi questa probabilmente non è un'idea fantastica al di fuori di questo scenario.

Non sembra esserci una convenzione specifica per Angular.JS per questo genere di cose. In effetti, Angular.JS non ha davvero molte convenzioni.

Invece di passare all'implementazione nel costruttore, in alternativa è possibile offrire un metodo separato per modificare il meccanismo di persistenza in qualsiasi momento. Ad esempio, per utilizzare ChartResource per il recupero iniziale basato sulla rete, quindi scambiando a IndexedDB per la memorizzazione in locale:

// ChartResourceIndexedDB: same API as $resource but uses local IndexedDB 
app.factory('ChartResourceIndexedDB', /* .. */); 

app.controller('ChartsCtrl', [ 
    '$scope', 'ChartResource', 'ChartResourceIndexedDB', 
    function($scope, ChartResource, ChartResourceIndexedDB) { 
    $scope.charts = $.map(ChartResource.query(), function(i, resource) { 
     chart = App.chart(resource) 
     chart.draw(); 
     chart.setPersistence(ChartResourceIndexedDB); 
     chart.save(); 
     return chart 
    } 
    } 
]); 
Problemi correlati