Współpracuję z AngularJS przy moim najnowszym projekcie. W dokumentacji i samouczkach wszystkie dane modelu są umieszczane w zakresie kontrolera. Rozumiem, że musi to być dostępne dla kontrolera, a zatem w ramach odpowiednich widoków.
Jednak nie sądzę, że model powinien tam zostać rzeczywiście wdrożony. Może być na przykład złożony i mieć prywatne atrybuty. Ponadto ktoś może chcieć ponownie użyć go w innym kontekście / aplikacji. Włożenie wszystkiego do kontrolera całkowicie psuje wzór MVC.
To samo dotyczy zachowania dowolnego modelu. Gdybym użył architektury DCI i oddzieliłby zachowanie od modelu danych, musiałbym wprowadzić dodatkowe obiekty, aby zachować to zachowanie. Odbyłoby się to poprzez wprowadzenie ról i kontekstów.
DCI == D ATA C ollaboration I nteraction
Oczywiście dane i zachowanie modelu można zaimplementować za pomocą zwykłych obiektów javascript lub dowolnego wzorca „klasy”. Ale jaki byłby sposób AngularJS? Korzystasz z usług?
Sprowadza się to do tego pytania:
W jaki sposób wdrażasz modele oddzielone od kontrolera zgodnie z najlepszymi praktykami AngularJS?
źródło
Odpowiedzi:
Powinieneś skorzystać z usług, jeśli chcesz czegoś użytecznego dla wielu kontrolerów. Oto prosty wymyślony przykład:
źródło
Obecnie próbuję tego wzorca, który, choć nie DCI, zapewnia klasyczne oddzielenie usługi / modelu (z usługami do komunikacji z usługami internetowymi (inaczej model CRUD) oraz modelem definiującym właściwości i metody obiektu).
Zauważ, że używam tego wzorca tylko wtedy, gdy obiekt modelu potrzebuje metod działających na własnych właściwościach, których prawdopodobnie będę używać wszędzie (takich jak ulepszony getter / setters). Ja nie promując w ten sposób dla każdej usługi w sposób systematyczny.
EDYCJA: Kiedyś myślałem, że ten wzór byłby sprzeczny z mantrą „Model kątowy to zwykły stary obiekt javascript”, ale wydaje mi się teraz, że ten wzór jest całkowicie w porządku.
EDYCJA (2): Aby być jeszcze jaśniejszym, używam klasy Model tylko po to, aby uwzględnić proste metody pobierające / ustawiające (np .: do użycia w szablonach widoku). W przypadku logiki dużego biznesu zalecam korzystanie z oddzielnych usług, które „wiedzą” o modelu, ale są oddzielone od nich i obejmują tylko logikę biznesową. Jeśli chcesz, możesz to nazwać warstwą usług „ekspertów biznesowych”
service / ElementServices.js (zauważ, jak element jest wstrzykiwany do deklaracji)
model / Element.js (przy użyciu angularjs Factory, stworzony do tworzenia obiektów)
źródło
Dokumentacja Angularjs wyraźnie stwierdza:
Oznacza to, że od Ciebie zależy, jak zadeklarować model. To prosty obiekt JavaScript.
Ja osobiście nie będę korzystać z usług Angular, ponieważ miały one zachowywać się jak obiekty singletonowe, których możesz użyć, na przykład, do utrzymania globalnych stanów w twojej aplikacji.
źródło
DCI jest paradygmatem i jako taki nie ma sposobu na angularJS, albo język obsługuje DCI, albo nie. JS obsługuje DCI raczej dobrze, jeśli chcesz użyć transformacji źródła i ma pewne wady, jeśli tak nie jest. Znowu DCI nie ma nic wspólnego z wstrzykiwaniem zależności, niż twierdzenie, że klasa C # ma i zdecydowanie nie jest usługą. Zatem najlepszym sposobem na wykonanie DCI z angulusJS jest wykonanie DCI w JS, co jest bardzo zbliżone do tego, jak DCI jest formułowane w pierwszej kolejności. O ile nie wykonasz transformacji źródłowej, nie będziesz w stanie tego zrobić w pełni, ponieważ metody roli będą częścią obiektu nawet poza kontekstem, ale generalnie jest to problem z DCI opartym na wstrzykiwaniu metod. Jeśli spojrzysz na fullOO.infoautorytatywną stronę dla DCI, możesz zapoznać się z implementacjami ruby, w których również używają metody wstrzykiwania, lub możesz zajrzeć tutaj, aby uzyskać więcej informacji na temat DCI. Dotyczy to głównie przykładów RUby, ale DCI jest agnostyczny. Jednym z kluczy do DCI jest to, że to, co robi system, jest oddzielone od tego, czym jest system. Tak więc obiekt danych jest dość głupi, ale po powiązaniu z rolą w kontekście metody roli udostępniają określone zachowanie. Rola jest po prostu identyfikatorem, nic więcej, a podczas uzyskiwania dostępu do obiektu za pomocą tego identyfikatora dostępne są metody ról. Nie ma obiektu roli / klasy. W przypadku wstrzykiwania metod ustalanie zakresu metod ról nie jest dokładnie zgodne z opisem, ale jest bliskie. Przykładem kontekstu w JS może być
źródło
Ten artykuł o modelach w AngularJS może pomóc:
http://joelhooks.com/blog/2013/04/24/modeling-data-and-state-in-your-angularjs-application/
źródło
Jak stwierdzono w innych plakatach, Angular nie zapewnia gotowej klasy bazowej do modelowania, ale można użytecznie udostępnić kilka funkcji:
Jedną biblioteką, która dobrze robi wszystkie te rzeczy, jest ngActiveResource ( https://github.com/FacultyCreative/ngActiveResource ). Pełne ujawnienie - napisałem tę bibliotekę - i z powodzeniem wykorzystałem ją do budowy kilku aplikacji na skalę korporacyjną. Jest dobrze przetestowany i zapewnia interfejs API, który powinien być znany programistom Railsów.
Mój zespół i ja nadal aktywnie rozwijamy tę bibliotekę i chciałbym zobaczyć, jak więcej programistów Angular wnosi do niej swój wkład i testuje ją w bitwie.
źródło
ngActiveResource
i Angulara$resource
. Jestem trochę nowy w Angular i szybko przejrzałem oba zestawy dokumentów, ale wydają się one nakładać na siebie. Czy zostałngActiveResource
opracowany przed udostępnieniem$resource
usługi?Starsze pytanie, ale myślę, że temat jest bardziej trafny niż kiedykolwiek, biorąc pod uwagę nowy kierunek Angular 2.0. Powiedziałbym, że najlepszą praktyką jest pisanie kodu przy możliwie najmniejszej zależności od konkretnego frameworka. Używaj tylko części specyficznych dla frameworka, jeżeli wnoszą one bezpośrednią wartość.
Obecnie wydaje się, że usługa Angular jest jedną z niewielu koncepcji, które pozwolą jej przejść do następnej generacji Angulara, więc prawdopodobnie rozsądnie jest postępować zgodnie z ogólną wytyczną dotyczącą przenoszenia całej logiki na usługi. Argumentowałbym jednak, że można tworzyć modele odsprzęgnięte, nawet bez bezpośredniej zależności od usług Angular. Tworzenie samodzielnych obiektów z tylko niezbędnymi zależnościami i obowiązkami jest prawdopodobnie dobrym rozwiązaniem. Ułatwia także życie podczas wykonywania testów automatycznych. Pojedyncza odpowiedzialność to w dzisiejszych czasach burzliwa praca, ale ma wiele sensu!
Oto przykład tupotu, który uważam za dobry do oddzielenia modelu obiektowego od dom.
http://www.syntaxsuccess.com/viewarticle/548ebac8ecdac75c8a09d58e
Kluczowym celem jest ustrukturyzowanie kodu w taki sposób, aby korzystanie z testów jednostkowych było równie łatwe, jak z widoku. Jeśli to osiągniesz, masz dobrą pozycję do pisania realistycznych i przydatnych testów.
źródło
Starałem się rozwiązać dokładnie ten problem w tym poście na blogu .
Zasadniczo najlepszym miejscem do modelowania danych są usługi i fabryki. Jednak w zależności od sposobu pobierania danych i złożoności zachowań, których potrzebujesz, istnieje wiele różnych sposobów realizacji. Obecnie Angular nie ma standardowego sposobu ani najlepszych praktyk.
Post obejmuje trzy podejścia, używając $ http , $ resource i Restangular .
Oto przykładowy kod dla każdego z niestandardową
getResult()
metodą w modelu Job:Restangular (łatwy peasy):
$ zasób (nieco bardziej skomplikowany):
$ http (hardcore):
Sam post na blogu zawiera bardziej szczegółowe informacje na temat uzasadnienia zastosowania każdego z tych podejść, a także przykłady kodu użycia modeli w kontrolerach:
Modele danych AngularJS: $ http VS $ zasób VS Restangular
Istnieje możliwość, że Angular 2.0 zaoferuje bardziej niezawodne rozwiązanie do modelowania danych, dzięki któremu wszyscy znajdą się na tej samej stronie.
źródło