css - ngstyle - tag template angular 2




Come includere la vista/lo stile specifico parziale in AngularJS (5)

Qual è il modo corretto / accettato di utilizzare fogli di stile separati per i vari punti di vista utilizzati dalla mia applicazione?

Attualmente sto posizionando un elemento link nella vista / partial in alto, ma mi è stato detto che è una pratica sbagliata anche se tutti i browser moderni lo supportano, ma posso capire perché è disapprovato.

L'altra possibilità è posizionare i fogli di stile separati nel mio index.html, ma mi piacerebbe che caricasse il foglio di stile solo se la sua vista veniva caricata nel nome del rendimento.

È una cattiva pratica dal momento che lo stile non ha effetto fino a quando il css non viene caricato dal server, portando a un rapido flash di contenuto non formattato in un browser lento? Devo ancora testimoniare questo, anche se lo sto testando localmente.

C'è un modo per caricare il CSS attraverso l'oggetto passato a $routeProvider.when ?

Grazie in anticipo!


'usare rigoroso'; angular.module ('app') .run (['$ rootScope', '$ stato', '$ stateParams', funzione ($ rootScope, $ stato, $ stateParams) {$ rootScope. $ stato = $ stato; $ rootScope . $ stateParams = $ stateParams;}]) .config (['$ stateProvider', '$ urlRouterProvider', funzione ($ stateProvider, $ urlRouterProvider) {

            $urlRouterProvider
                .otherwise('/app/dashboard');
            $stateProvider
                .state('app', {
                    abstract: true,
                    url: '/app',
                    templateUrl: 'views/layout.html'
                })
                .state('app.dashboard', {
                    url: '/dashboard',
                    templateUrl: 'views/dashboard.html',
                    ncyBreadcrumb: {
                        label: 'Dashboard',
                        description: ''
                    },
                    resolve: {
                        deps: [
                            '$ocLazyLoad',
                            function($ocLazyLoad) {
                                return $ocLazyLoad.load({
                                    serie: true,
                                    files: [
                                        'lib/jquery/charts/sparkline/jquery.sparkline.js',
                                        'lib/jquery/charts/easypiechart/jquery.easypiechart.js',
                                        'lib/jquery/charts/flot/jquery.flot.js',
                                        'lib/jquery/charts/flot/jquery.flot.resize.js',
                                        'lib/jquery/charts/flot/jquery.flot.pie.js',
                                        'lib/jquery/charts/flot/jquery.flot.tooltip.js',
                                        'lib/jquery/charts/flot/jquery.flot.orderBars.js',
                                        'app/controllers/dashboard.js',
                                        'app/directives/realtimechart.js'
                                    ]
                                });
                            }
                        ]
                    }
                })
                .state('ram', {
                    abstract: true,
                    url: '/ram',
                    templateUrl: 'views/layout-ram.html'
                })
                .state('ram.dashboard', {
                    url: '/dashboard',
                    templateUrl: 'views/dashboard-ram.html',
                    ncyBreadcrumb: {
                        label: 'test'
                    },
                    resolve: {
                        deps: [
                            '$ocLazyLoad',
                            function($ocLazyLoad) {
                                return $ocLazyLoad.load({
                                    serie: true,
                                    files: [
                                        'lib/jquery/charts/sparkline/jquery.sparkline.js',
                                        'lib/jquery/charts/easypiechart/jquery.easypiechart.js',
                                        'lib/jquery/charts/flot/jquery.flot.js',
                                        'lib/jquery/charts/flot/jquery.flot.resize.js',
                                        'lib/jquery/charts/flot/jquery.flot.pie.js',
                                        'lib/jquery/charts/flot/jquery.flot.tooltip.js',
                                        'lib/jquery/charts/flot/jquery.flot.orderBars.js',
                                        'app/controllers/dashboard.js',
                                        'app/directives/realtimechart.js'
                                    ]
                                });
                            }
                        ]
                    }
                })
                 );

@ sz3, abbastanza divertente oggi ho dovuto fare esattamente quello che stavi cercando di ottenere: ' carica un file CSS specifico solo quando un utente accede ' ad una pagina specifica. Quindi ho usato la soluzione sopra.

Ma sono qui per rispondere alla tua ultima domanda: ' dove esattamente dovrei inserire il codice. Qualche idea ?

Hai ragione includendo il codice nella risoluzione , ma è necessario modificare leggermente il formato.

Dai un'occhiata al codice qui sotto:

.when('/home', {
  title:'Home - ' + siteName,
  bodyClass: 'home',
  templateUrl: function(params) {
    return 'views/home.html';
  },
  controler: 'homeCtrl',
  resolve: {
    style : function(){
      /* check if already exists first - note ID used on link element*/
      /* could also track within scope object*/
      if( !angular.element('link#mobile').length){
        angular.element('head').append('<link id="home" href="home.css" rel="stylesheet">');
      }
    }
  }
})

Ho appena testato e funziona bene , inietta l'html e carica il mio 'home.css' solo quando raggiungo la rotta '/ home'.

La spiegazione completa può essere trovata here , ma sostanzialmente risolta: dovrebbe ottenere un oggetto nel formato

{
  'key' : string or function()
} 

Puoi nominare la ' chiave ' qualsiasi cosa tu voglia - nel mio caso ho chiamato ' stile '.

Quindi per il valore hai due opzioni:

  • Se si tratta di una stringa , allora è un alias per un servizio.

  • Se è funzione , viene iniettata e il valore di ritorno viene considerato come dipendenza.

Il punto principale qui è che il codice all'interno della funzione verrà eseguito prima dell'istanza del controller e viene generato l'evento $ routeChangeSuccess.

Spero possa aiutare.


La soluzione di @ tennisgent è fantastica. Tuttavia, penso che sia un po 'limitato.

La modularità e l'incapsulamento in Angular vanno oltre le rotte. Sulla base del modo in cui il web si sta spostando verso lo sviluppo basato sui componenti, è importante applicarlo anche nelle direttive.

Come già sapete, in Angular possiamo includere modelli (struttura) e controller (comportamento) in pagine e componenti. AngularCSS abilita l'ultimo pezzo mancante: allegando i fogli di stile (presentazione).

Per una soluzione completa, suggerisco di utilizzare AngularCSS.

  1. Supporta Angular's ngRoute, UI Router, direttive, controller e servizi.
  2. Non è necessario avere ng-app nel tag <html> . Questo è importante quando hai più app in esecuzione sulla stessa pagina
  3. Puoi personalizzare dove vengono iniettati i fogli di stile: testa, corpo, selettore personalizzato, ecc ...
  4. Supporta il precaricamento, la persistenza e il busting della cache
  5. Supporta le query multimediali e ottimizza il caricamento della pagina tramite l'API matchMedia

https://github.com/door3/angular-css

Ecco alcuni esempi:

Itinerari

  $routeProvider
    .when('/page1', {
      templateUrl: 'page1/page1.html',
      controller: 'page1Ctrl',
      /* Now you can bind css to routes */
      css: 'page1/page1.css'
    })
    .when('/page2', {
      templateUrl: 'page2/page2.html',
      controller: 'page2Ctrl',
      /* You can also enable features like bust cache, persist and preload */
      css: {
        href: 'page2/page2.css',
        bustCache: true
      }
    })
    .when('/page3', {
      templateUrl: 'page3/page3.html',
      controller: 'page3Ctrl',
      /* This is how you can include multiple stylesheets */
      css: ['page3/page3.css','page3/page3-2.css']
    })
    .when('/page4', {
      templateUrl: 'page4/page4.html',
      controller: 'page4Ctrl',
      css: [
        {
          href: 'page4/page4.css',
          persist: true
        }, {
          href: 'page4/page4.mobile.css',
          /* Media Query support via window.matchMedia API
           * This will only add the stylesheet if the breakpoint matches */
          media: 'screen and (max-width : 768px)'
        }, {
          href: 'page4/page4.print.css',
          media: 'print'
        }
      ]
    });

direttive

myApp.directive('myDirective', function () {
  return {
    restrict: 'E',
    templateUrl: 'my-directive/my-directive.html',
    css: 'my-directive/my-directive.css'
  }
});

Inoltre, è possibile utilizzare il servizio $css per i casi limite:

myApp.controller('pageCtrl', function ($scope, $css) {

  // Binds stylesheet(s) to scope create/destroy events (recommended over add/remove)
  $css.bind({ 
    href: 'my-page/my-page.css'
  }, $scope);

  // Simply add stylesheet(s)
  $css.add('my-page/my-page.css');

  // Simply remove stylesheet(s)
  $css.remove(['my-page/my-page.css','my-page/my-page2.css']);

  // Remove all stylesheets
  $css.removeAll();

});

Puoi leggere ulteriori informazioni su AngularCSS qui:

http://door3.com/insights/introducing-angularcss-css-demand-angularjs


Potrebbe aggiungere un nuovo foglio di stile alla testa all'interno di $routeProvider . Per semplicità sto usando una stringa ma potrei creare anche un nuovo elemento di collegamento, o creare un servizio per i fogli di stile

/* check if already exists first - note ID used on link element*/
/* could also track within scope object*/
if( !angular.element('link#myViewName').length){
    angular.element('head').append('<link id="myViewName" href="myViewName.css" rel="stylesheet">');
}

Il più grande vantaggio di pre-pagina nella pagina è che esistono già tutte le immagini di sfondo e meno menzogne ​​del FOUC


So che questa domanda è vecchia ora, ma dopo aver fatto un sacco di ricerche su varie soluzioni a questo problema, penso che potrei aver trovato una soluzione migliore.

AGGIORNAMENTO 1: Da quando ho postato questa risposta, ho aggiunto tutto questo codice a un servizio semplice che ho pubblicato su GitHub. Il repository si trova here . Sentiti libero di darci un'occhiata per maggiori informazioni.

AGGIORNAMENTO 2: questa risposta è ottima se tutto ciò di cui hai bisogno è una soluzione leggera per l'estrazione di fogli di stile per i tuoi percorsi. Se si desidera una soluzione più completa per la gestione di fogli di stile su richiesta all'interno dell'applicazione, è possibile eseguire il checkout del progetto AngularCSS di Door3 . Fornisce funzionalità molto più fini.

Nel caso in cui qualcuno in futuro sia interessato, ecco cosa mi è venuto in mente:

1. Creare una direttiva personalizzata per l'elemento <head> :

app.directive('head', ['$rootScope','$compile',
    function($rootScope, $compile){
        return {
            restrict: 'E',
            link: function(scope, elem){
                var html = '<link rel="stylesheet" ng-repeat="(routeCtrl, cssUrl) in routeStyles" ng-href="{{cssUrl}}" />';
                elem.append($compile(html)(scope));
                scope.routeStyles = {};
                $rootScope.$on('$routeChangeStart', function (e, next, current) {
                    if(current && current.$$route && current.$$route.css){
                        if(!angular.isArray(current.$$route.css)){
                            current.$$route.css = [current.$$route.css];
                        }
                        angular.forEach(current.$$route.css, function(sheet){
                            delete scope.routeStyles[sheet];
                        });
                    }
                    if(next && next.$$route && next.$$route.css){
                        if(!angular.isArray(next.$$route.css)){
                            next.$$route.css = [next.$$route.css];
                        }
                        angular.forEach(next.$$route.css, function(sheet){
                            scope.routeStyles[sheet] = sheet;
                        });
                    }
                });
            }
        };
    }
]);

Questa direttiva fa le seguenti cose:

  1. Compila (usando $compile ) una stringa html che crea un insieme di <link /> per ogni oggetto nell'oggetto scope.routeStyles usando ng-repeat e ng-href .
  2. Aggiunge il set compilato di <link /> elementi al tag <head> .
  3. Quindi usa $rootScope per ascoltare '$routeChangeStart' eventi '$routeChangeStart' . Per ogni evento '$routeChangeStart' , afferra l'oggetto del $$route "corrente" (il percorso che l'utente sta per lasciare) e rimuove i suoi file css parziali specifici dal tag <head> . Afferra anche l'oggetto "next" $$route (la rotta a cui l'utente sta per andare) e aggiunge uno qualsiasi dei suoi file css parziali specifici al tag <head> .
  4. E la parte ng-repeat del tag <link /> compilato gestisce tutto l'aggiunta e la rimozione dei fogli di stile specifici della pagina in base a ciò che viene aggiunto o rimosso dall'oggetto scope.routeStyles .

Nota: questo richiede che l'attributo ng-app si trovi sull'elemento <html> , non su <body> o qualsiasi cosa all'interno di <html> .

2. Specificare quali fogli di stile appartengono a quali percorsi utilizzare $routeProvider :

app.config(['$routeProvider', function($routeProvider){
    $routeProvider
        .when('/some/route/1', {
            templateUrl: 'partials/partial1.html', 
            controller: 'Partial1Ctrl',
            css: 'css/partial1.css'
        })
        .when('/some/route/2', {
            templateUrl: 'partials/partial2.html',
            controller: 'Partial2Ctrl'
        })
        .when('/some/route/3', {
            templateUrl: 'partials/partial3.html',
            controller: 'Partial3Ctrl',
            css: ['css/partial3_1.css','css/partial3_2.css']
        })
}]);

Questa configurazione aggiunge una proprietà css personalizzata all'oggetto che viene utilizzato per impostare il percorso di ogni pagina. '$routeChangeStart' viene passato a ogni evento '$routeChangeStart' come .$$route . Quindi, ascoltando l'evento '$routeChangeStart' , possiamo prendere la proprietà css che abbiamo specificato e aggiungere / rimuovere quei <link /> se necessario. Nota che specificare una proprietà css sul percorso è completamente opzionale, poiché è stato omesso dall'esempio '/some/route/2' . Se la rotta non ha una proprietà css , la direttiva <head> semplicemente non farà nulla per quella rotta. Si noti inoltre che è possibile avere anche più fogli di stile specifici per pagina per rotta, come nell'esempio '/some/route/3' sopra, dove la proprietà css è una matrice di percorsi relativi ai fogli di stile necessari per quella rotta.

3. Hai finito Queste due cose impostano tutto ciò che era necessario e lo fa, secondo me, con il codice più pulito possibile.

Spero che aiuti qualcun altro che potrebbe essere alle prese con questo problema tanto quanto lo ero io.







angularjs