2013-07-02 12 views
7

Jestem nowy w Angular, więc mam nadzieję, że wiem wystarczająco dużo, aby zadać pytanie, co wydaje się rozsądnym pytaniem projektowym.Wzorzec Active Record lub Mapper danych dla Angularjs?

Mam wykres niektórych danych za pośrednictwem Angular i używam $ zasób. Przed wprowadzeniem Angular do projektu stworzyłem funkcję fabryki wykresów do tworzenia obiektów wykresów z przykładowych danych jsonów, które właśnie wkleiłem do widoku.

Teraz używam kątowe, aż korci, żeby umieścić funkcje wykresów w „Chart” zasobu, aktywny styl Record, tak, że mam tę jedną rzecz, która może pobierać, zapisywać, aktualizacji, itp

Chociaż zaletą tego wzoru jest prostota, wadą jest powiązanie trwałości z zachowaniem. Na przykład byłoby niezręcznie, gdybym chciał zapisać ustawienia wykresu w pamięci lokalnej.

Po tym, jak byłem już ugryziony przez AR wystarczająco dużo razy w mojej karierze, chcę iść z DM przez pozostawienie mojego obiektu wykresu tak jak jest i posiadanie kontrolera przekazuje dane z zasobu do mojego wykresu.

Jednak! Moje niewyraźne zrozumienie zastrzyku zależności angularjs sugeruje, że mogę być w stanie stworzyć zasób lub takie, które mogłyby przyjąć wspólny interfejs trwałości - czy właściwe słowo to "zakres"? Strategia

Przykład 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() }) 
    }) 
    } 
]) 

Przykład 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 
    } 
    } 
]) 

myślę, że istnieje trzecia droga, chociaż, że nie widzę, bo nie dość grok jak wykorzystać DI.

Innymi słowy, jaki jest sposób AngularJS na stworzenie obiektu z wymienialnymi strategiami trwałości?

+0

ten powinien być bardziej widoczny, ponieważ jest częstym problemem przy projektowaniu aplikacji angularjs poważne. – Danita

+0

Zastanawiam się, czy ChartResource będzie zależało od wykresu i doda wywołanie zwrotne do wywołania, które odebrałoby odebrane dane i spowodowałoby powstanie nowej instancji Chart.W ten sposób kontroler może wywołać ChartResource lub LocalStorageChart (lub usługę, która wywołuje LocalStorageChart i używa ChartResource jako awarię \, gdy czas upłynie, aby unieważnić). Co myślisz? – haimlit

Odpowiedz

3

Strategia DataMapper jest już formą Dependency Injection. Przekazujesz żądaną implementację utrwalania do konstruktora wykresów i możesz przekazać inną wartość na podstawie new. Metoda nie-DI polegałaby na twardym kodowaniu implementacji trwałości, tak jak w przykładzie w stylu ActiveRecord.

DataMapper nie jest DI w specyficznym dla Angular.JS znaczeniu tego terminu. Diagram DI Angular nie pozwala na zamianę implementacji w czasie wykonywania. Możesz jednak użyć oficjalnego modułu ngMock, aby to osiągnąć. NgMock ma być używany do testowania, więc prawdopodobnie nie jest to świetny pomysł poza tym scenariuszem.

Wydaje się, że nie istnieje konwencja specyficzna dla Angular.JS dla tego rodzaju rzeczy. W rzeczywistości Angular.JS naprawdę nie ma wielu konwencji.

Zamiast przekazywać implementację w konstruktorze, można w dowolnym momencie zaoferować osobną metodę zmiany mechanizmu utrwalania. Na przykład, aby użyć ChartResource do wstępnego pobierania sieciowego, a następnie zamiana na IndexedDB przechowywać je lokalnie:

// 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 
    } 
    } 
]); 
Powiązane problemy