Czy istnieje sposób, aby AngularJS ładował częściowe na początku, a nie w razie potrzeby?

190

Mam taką konfigurację trasy:

var myApp = angular.module('myApp', []).
    config(['$routeProvider', function ($routeProvider) {
    $routeProvider.
        when('/landing', {
            templateUrl: '/landing-partial',
            controller: landingController
        }).
        when('/:wkspId/query', {
            templateUrl: '/query-partial',
            controller: queryController
        }).
        otherwise({
            redirectTo: '/landing'
        });
}]);

Chcę być w stanie zmusić angularjs do pobrania obu części na początku, a nie na żądanie.

Czy to możliwe?

Ranjith Ramachandra
źródło

Odpowiedzi:

270

Tak, istnieją co najmniej 2 rozwiązania tego:

  1. Użyj scriptdyrektywy ( http://docs.angularjs.org/api/ng.directive:script ), aby umieścić swoje częściowe w początkowo załadowanym HTML
  2. W razie potrzeby możesz również wypełnić $templateCache( http://docs.angularjs.org/api/ng.$templateCache ) z JavaScript (ewentualnie na podstawie wyniku $httpwywołania)

Jeśli chcesz użyć metody (2) do wypełnienia $templateCache, możesz to zrobić w następujący sposób:

$templateCache.put('second.html', '<b>Second</b> template');

Oczywiście treść szablonów może pochodzić z $httppołączenia:

$http.get('third.html', {cache:$templateCache});

Oto plunker tych technik: http://plnkr.co/edit/J6Y2dc?p=preview

pkozlowski.opensource
źródło
2
Dziękuję za odpowiedź. Podoba mi się pomysł na pamięć podręczną szablonów, ponieważ nie chcę umieszczać rzeczy w tagu skryptu. Jak tego użyć? Dokumentacja jest zła. Widziałem skrzypce w jednym z komentarzy tam. Ale chcę załadować z adresu URL.
Ranjith Ramachandra
Zaktualizowałem odpowiedź na podstawie komentarzy
pkozlowski.opensource
4
Czasami używam <script>tagu wbudowanego wraz z dołączeniami po stronie serwera. To pozwala mi przechowywać moje częściowe jako osobne pliki do celów organizacyjnych, ale nadal dostarcza wszystko w jednym dokumencie.
Blazemonger
2
Czy wiesz, czy istnieje przyspieszenie w wyborze jednego rozwiązania zamiast drugiego?
Atav32
2
Szablony buforuję za pomocą wywołania HTTP, ale problemem jest nazwa szablonu buforowanego to przykładowy adres URL: $ http.get ('app / korekta / szablony / grupa-korekta-tabela.html', {pamięć podręczna: $ templateCache}); a następnie za każdym razem, gdy chcę załadować szablon, muszę użyć tej brzydkiej nazwy :( której nie lubię, na przykład: <td ng-include = "'app /cja / szablony / grupa-korekta-tabela.html' ">
Shilan,
25

Jeśli użyjesz Grunta do zbudowania swojego projektu, istnieje wtyczka, która automatycznie połączy twoje częściowe w moduł Angular, który ładuje $ templateCache. Możesz połączyć ten moduł z resztą kodu i załadować wszystko z jednego pliku podczas uruchamiania.

https://npmjs.org/package/grunt-html2js

Karlgold
źródło
11
Jest też coś, grunt-angular-templatesco robi to samo - npmjs.org/package/grunt-angular-templates - działa na ucztę
Ben Walding
Czy działa to również w przypadku szablonów w pliku indeksu? Mam plik ng-view i ng-include w moim pliku indeksu i mam problem z wyświetleniem mojej aplikacji.
Batman
16

Dodaj zadanie kompilacji, aby połączyć i zarejestrować swoje częściowe HTML w Angular $templateCache. ( Ta odpowiedź jest bardziej szczegółowym wariantem odpowiedzi Karlgolda. )

Do chrząkania użyj szablonów chropowatych . W przypadku łyka użyj gulp-angular-templatecache .

Poniżej znajdują się fragmenty konfiguracji / kodu do zilustrowania.

gruntfile.js Przykład:

ngtemplates: {
  app: {                
    src: ['app/partials/**.html', 'app/views/**.html'],
    dest: 'app/scripts/templates.js'
  },
  options: {
    module: 'myModule'
  }
}

gulpfile.js Przykład:

var templateCache = require('gulp-angular-templatecache');
var paths = ['app/partials/.html', 'app/views/.html'];

gulp.task('createTemplateCache', function () {
return gulp.src(paths)
    .pipe(templateCache('templates.js', { module: 'myModule', root:'app/views'}))
    .pipe(gulp.dest('app/scripts'));
    });

templates.js (ten plik jest generowany automatycznie przez zadanie kompilacji)

$templateCache.put('app/views/main.html', "<div class=\"main\">\r"...

index.html

<script src="app/scripts/templates.js"></script>
<div ng-include ng-controller="main as vm" src="'app/views/main.html'"></div>
James Lawruk
źródło
2
Cześć @james Używam tej wtyczki Gulp. Wszystkie pliki .html ładują się poprawnie, ale kiedy próbuję określić HTML jako część wtyczki okna dialogowego (używam ng-material), wyrzuca 404. ex - $ mdDialog.show ({controller: 'entityGridCtrl', templateUrl: 'user / częściowe / entityGrid.html '});
Anand
Czy zastąpiłeś odniesienia do mojej aplikacji / widoków swoim użytkownikiem / częściami?
James Lawruk
Dzięki. Nie zmieniam ścieżki częściowych, wysłałem swoje pytanie - stackoverflow.com/questions/29399453/...
Anand
11

Jeśli otoczysz każdy szablon znacznikiem skryptowym, np .:

<script id="about.html" type="text/ng-template">
<div>
    <h3>About</h3>
    This is the About page
    Its cool!
</div>
</script>

Połącz wszystkie szablony w 1 duży plik. Jeśli korzystasz z programu Visual Studio 2013, pobierz podstawowe informacje o sieci - dodaje menu prawym przyciskiem myszy, aby utworzyć pakiet HTML.

Dodaj kod, który ten facet napisał, aby zmienić $templatecacheusługę kątową - to tylko mały fragment kodu i działa: Gist Vojty Jiny

To $http.getnależy zmienić, aby użyć pliku pakietu:

allTplPromise = $http.get('templates/templateBundle.min.html').then(

Twoje trasy templateUrlpowinny wyglądać tak:

        $routeProvider.when(
            "/about", {
                controller: "",
                templateUrl: "about.html"
            }
        );
Simon Dowdeswell
źródło
0

Po prostu ecorobię to dla siebie. ecojest domyślnie obsługiwany przez Sprockets. Jest to skrót od Embedded Coffeescript, który pobiera plik eco i kompiluje do pliku szablonu JavaScript, a plik będzie traktowany jak każdy inny plik js, który masz w folderze zasobów.

Wszystko, co musisz zrobić, to utworzyć szablon z rozszerzeniem .jst.eco i napisać tam kod HTML, a szyny automatycznie skompilują się i udostępnią plik z potokiem zasobów, a dostęp do szablonu jest naprawdę łatwy: JST['path/to/file']({var: value});gdzie path/to/fileopiera się na ścieżce logicznej, więc jeśli masz plik /assets/javascript/path/file.jst.eco, możesz uzyskać dostęp do szablonu pod adresemJST['path/file']()

Aby działał z angularjs, możesz przekazać go do atrybutu template zamiast templateDir i zacznie on działać magicznie!

Ołówek
źródło
Nie jestem pewien, czy to odpowiada na pytanie, a zmiana języka programowania jest prawdopodobnie przesadą.
xdhmoore
0

Możesz przekazać stan $ do swojego kontrolera, a następnie gdy strona ładuje się i wywołuje getter w kontrolerze, wywołujesz $ state.go („indeks”) lub dowolną część, którą chcesz załadować. Gotowe.

rj905
źródło
-1

Inną metodą jest użycie pamięci podręcznej aplikacji HTML5 do jednokrotnego pobrania wszystkich plików i zachowania ich w pamięci podręcznej przeglądarki. Powyższy link zawiera znacznie więcej informacji. Z artykułu pochodzą następujące informacje:

Zmień <html>tag, aby zawierał manifestatrybut:

<html manifest="http://www.example.com/example.mf">

Plik manifestu musi zostać podany z typem MIME text/cache-manifest .

Prosty manifest wygląda mniej więcej tak:

CACHE MANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js
http://cdn.example.com/scripts/main.js

Gdy aplikacja jest offline, pozostaje w pamięci podręcznej, dopóki nie zdarzy się jedna z poniższych sytuacji:

  1. Użytkownik usuwa dane z przeglądarki w Twojej witrynie.
  2. Plik manifestu został zmodyfikowany. Uwaga: aktualizacja pliku wymienionego w manifeście nie oznacza, że ​​przeglądarka ponownie buforuje ten zasób. Sam plik manifestu musi zostać zmieniony.
Brent Washburne
źródło
1
niestety ta funkcja jest obecnie przestarzała developer.mozilla.org/en-US/docs/Web/HTML/… więc tylko heads-up, skorzystaj z tego podejścia na własne ryzyko
Lazy Coder
Zgodnie ze standardem HTML „Ta funkcja jest właśnie usuwana z platformy internetowej. (Jest to długi proces, który trwa wiele lat).” Sugerowana zamiana, Service Workers, jest nadal „technologią eksperymentalną” na początku 2016 r. Na razie nadal używam pamięci podręcznej aplikacji, ponieważ działa ona dobrze w moich aplikacjach.
Brent Washburne