Skip to content
This repository was archived by the owner on Nov 22, 2024. It is now read-only.
This repository was archived by the owner on Nov 22, 2024. It is now read-only.

create universal services #309

Closed
Closed

Description

@PatrickJS

blocked via angular/angular#7455

  • NgStyleHost directive to use NodeDomSharedStylesHost added via e8befd4
    renamed via d804d7a
  • NgTitle directive to use Title service
  • NgMeta directive to use MetaTag Service
  • NgBase directive to use BaseUrl service
  • NgModule directive to precompile inline scripts
  • NgScript directive to precompile inline ts scripts
  • NgPreboot directive for precompiled client preboot

Activity

  1. self-assigned this
    on Mar 7, 2016
  2. PatrickJS commented on Mar 9, 2016

    @PatrickJS
    ContributorAuthor

    we're waiting for the next next release

  3. PatrickJS commented on Apr 15, 2016

    @PatrickJS
    ContributorAuthor

    <universal-styles> was added

  4. PatrickJS commented on Apr 20, 2016

    @PatrickJS
    ContributorAuthor

    I'm adding NgPreboot

  5. jeffwhelpley commented on May 6, 2016

    @jeffwhelpley
    Contributor

    @gdi2290 What is the status here? Does it make sense to have so many different things in one issue? As we discussed, we should create a new module under Universal with all the common services people will need. I am modifying the title for this issue to reflect that.

  6. changed the title [-]create index.html directives[/-] [+]create universal services[/+] on May 6, 2016
  7. megalepozy commented on Jun 7, 2016

    @megalepozy

    I'm not sure if it's the right place to ask for it but is there something like NgLink for setting canonical links? it's badly needed for SEO

  8. jeffwhelpley commented on Jun 8, 2016

    @jeffwhelpley
    Contributor

    @megalepozy I agree with this. We should have one of the universal services that automatically sets the canonical link in the head. Also, related is i18n href lang tags.

  9. jeffwhelpley commented on Oct 5, 2016

    @jeffwhelpley
    Contributor

    As posted by @Quixomatic, the workaround for now is:

    import { Injectable, Inject, ElementRef, Renderer } from '@angular/core'
    import { DOCUMENT } from '@angular/platform-browser'
    
    @Injectable()
    export class InterfaceService {    
        //--------------------------------------------
        //! Set the variables to their default values
        //--------------------------------------------
        constructor (@Inject(DOCUMENT) private document) {
        }
    
        //----------------------------
        //! Set the title of the page
        //----------------------------
        setTitle (title: string) {
            this.document.title = title
        }
    }
    

    It will still be good to create these universal services, but this workaround is pretty simple and should cover setting the title.

  10. 10 remaining items

  11. threesquared commented on Oct 12, 2016

    @threesquared

    As a pretty hacky solution I mentioned above you can access getDOM() as I have done here which works at the moment...

  12. PatrickJS commented on Oct 27, 2016

    @PatrickJS
    ContributorAuthor

    closing as <html> component isn't supported by angular anymore

  13. threesquared commented on Oct 27, 2016

    @threesquared

    @gdi2290 @jeffwhelpley mentioned above that this thread would be updated with details of a meta tag service?

  14. samvloeberghs commented on Nov 15, 2016

    @samvloeberghs

    @threesquared do you mind if I use your implementation for now? Works like a charm :)

  15. PatrickJS commented on Nov 16, 2016

    @PatrickJS
    ContributorAuthor

    @threesquared please see PR angular/angular#12322 for more details on the Meta Service

  16. threesquared commented on Nov 16, 2016

    @threesquared

    @gdi2290 thanks!
    @samvloeberghs of course.

  17. marklonquist commented on Nov 30, 2016

    @marklonquist

    The suggestion in #309 (comment) did not work for me for setting the title serverside. I'm getting a 'data' is undefined error.

    Works fine if I use it client-side.

  18. ilDon commented on Jan 7, 2017

    @ilDon

    Not sure if still of interest, but putting together all suggestions found here and around, I've come up with a solution that is working well for me:

    import { Component, AfterViewInit, Renderer, Inject } from '@angular/core';
    import { DOCUMENT } from '@angular/platform-browser';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements AfterViewInit {
      constructor(@Inject(DOCUMENT) private document: any, private renderer: Renderer) {}
    
      ngAfterViewInit(): void {
        let headChildren = this.document.head.children;
        for (let i = 0; i < headChildren.length; i++) {
          let element = headChildren[i];
          if(element.name === 'title') this.renderer.setText(element, 'App title');
          if(element.name === 'meta' && element.attribs.translatestring) this.renderer.setElementAttribute(element, 'content', 'I am a translated string');
        }
    
        // To add new meta
        const elem = this.renderer.createElement(this.document.head, 'meta');
        this.renderer.setElementProperty(elem, 'name', 'foo');
      }
    }
    

    If you need this also client side you can simply transform this into a service, and then call it each time the route changes, then use this.renderer.setElementAttribute to change the attribute content to the right strings (e.g. from a constant with all the values based on the route).

  19. DBuit commented on Feb 1, 2017

    @DBuit

    @ghego1 i tried to use your for loop to set meta tags in the InterfaceServer

    import { Injectable, Inject, ElementRef, Renderer } from '@angular/core'
    import { DOCUMENT } from '@angular/platform-browser'
    
    @Injectable()
    export class InterfaceService {    
        //--------------------------------------------
        //! Set the variables to their default values
        //--------------------------------------------
        constructor (@Inject(DOCUMENT) private document) {
        }
    
        //----------------------------
        //! Set the title of the page
        //----------------------------
        setTitle (title: string) {
            this.document.title = title
        }
    }
    

    But im gettings this error: "No provider for ElementRef!", can you help me?

  20. ilDon commented on Feb 1, 2017

    @ilDon

    @DBuit, I think the problem is that you are doing this in a Service. I implemented this in a component, and then passed to the service the rendered object.

    I have not yet studied how Angular2 works behind the scenes so I'm unable to provide you a full description of why this can't be delegated entirely to a Service, but I can share with you the following working code :-)

    Component:

    import { Component, AfterViewInit, Renderer } from '@angular/core';
    
    import { MetaSetterService } from './wherever/meta-setter.service';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css']
    })
    export class AppComponent implements AfterViewInit {
    
      constructor(private metaSetter: MetaSetterService, public renderer: Renderer) { }
    
      ngAfterViewInit(): void {
          this.metaSetter.setAll(this.renderer);
      }
    
    }
    

    And then the service:

    import { Injectable, Inject } from '@angular/core';
    import { DOCUMENT } from '@angular/platform-browser';
    
    @Injectable()
    export class MetaSetterService {
    
      constructor(@Inject(DOCUMENT) private document: any) {}
    
      private renderer: any;
    
      public setAll(renderer: any): void {
        this.renderer = renderer;
        this.document.head.children.forEach( element => this.recurseAllHeadNodes(element) );
      }
    
      private recurseAllHeadNodes(element: any): void {
        if(element.name === 'title') this.renderer.setText(element, 'myTitle');
        else if(element.name === 'meta') this.renderer.setElementAttribute(element, 'content', 'myMeta');
      }
    
    }
    
  21. jrmcdona commented on Aug 1, 2017

    @jrmcdona

    Does this work well with dyanmic link and script tags from an external service?

  22. raviguru123 commented on Nov 17, 2018

    @raviguru123

    hi @ilDon, your solution does not work when we open view page source angular (SSE), can you please give support with angular SSE as well,
    i am using this for adding canonical URl

  23. angular-automatic-lock-bot commented on Sep 4, 2019

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  24. locked and limited conversation to collaborators on Sep 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions