0
votes

I have a dynamic id as shown below.Can you tell me how to get this id from the component (ts) file?

Note: My requirement here is, I need to scroll the content to that dynamic item when the user clicks a button (actually here is an item of Bar chart.I can handle that.)

.html

<ion-card *ngFor="let interval of intervals; let i = index" id="{{interval.key}}">
    <ion-card-header>
      {{interval.sleepingTimeRange}} {{interval.timeDuration}}
    </ion-card-header>
    <ion-card-content>
      {{interval.notes}}
    </ion-card-content>
  </ion-card>

I have tried as shown below.But I know this is a very BAD way of doing that.How can I do this using Angular 4 Renderer2?

.ts

 scrollTo(elementId: string) {
        let yOffset = document.getElementById(elementId).offsetTop;//This is BAD
        this.content.scrollTo(0, yOffset, 4000)
    }

This is the method where scrollTo() is being called.

subscribeIntervals(): void {
        this.events.subscribe('intervals', (data, selectedItem) => {
            this.intervals = [];

            _.forEach(data, (value, key) => {
                let interval: any = {
                    notes: '',
                 };

                interval.key = value.key;
                this.intervals.push(interval);
            });

            this.scrollTo(selectedItem.key);//scroll to

        });
    }

Error: When implemented the @Günter Zöchbauer solution

polyfills.js:3 Error: Uncaught (in promise): Error: Template parse errors: Can't bind to 'scrollIntoView' since it isn't a known property of 'ion-card'. 1. If 'ion-card' is an Angular component and it has 'scrollIntoView' input, then verify that it is part of this module. 2. If 'ion-card' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. 3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. ("

][scrollIntoView]="interval.key">

<ion-card-header> "): ng:///AppModule/SummaryPage.html@96:62 Error: Template parse errors: Can't bind to 'scrollIntoView' since it

isn't a known property of 'ion-card'. 1. If 'ion-card' is an Angular component and it has 'scrollIntoView' input, then verify that it is part of this module. 2. If 'ion-card' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message. 3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component. ("

][scrollIntoView]="interval.key">

<ion-card-header> "): ng:///AppModule/SummaryPage.html@96:62
at g (http://localhost:8100/build/polyfills.js:3:7133)
at syntaxError (http://localhost:8100/build/main.js:113362:34)
at TemplateParser.parse (http://localhost:8100/build/main.js:123371:19)
at JitCompiler._compileTemplate (http://localhost:8100/build/main.js:137054:39)
at http://localhost:8100/build/main.js:136978:62
at Set.forEach (native)
at JitCompiler._compileComponents (http://localhost:8100/build/main.js:136978:19)
at createResult (http://localhost:8100/build/main.js:136863:19)
at t.invoke (http://localhost:8100/build/polyfills.js:3:14529)
at n.run (http://localhost:8100/build/polyfills.js:3:9741)
at http://localhost:8100/build/polyfills.js:3:6774
at t.invokeTask (http://localhost:8100/build/polyfills.js:3:15213)
at n.runTask (http://localhost:8100/build/polyfills.js:3:10390)
at a (http://localhost:8100/build/polyfills.js:3:5313)
at g (http://localhost:8100/build/polyfills.js:3:7133)
at syntaxError (http://localhost:8100/build/main.js:113362:34)
at TemplateParser.parse (http://localhost:8100/build/main.js:123371:19)
at JitCompiler._compileTemplate (http://localhost:8100/build/main.js:137054:39)
at http://localhost:8100/build/main.js:136978:62
at Set.forEach (native)
at JitCompiler._compileComponents (http://localhost:8100/build/main.js:136978:19)
at createResult (http://localhost:8100/build/main.js:136863:19)
at t.invoke (http://localhost:8100/build/polyfills.js:3:14529)
at n.run (http://localhost:8100/build/polyfills.js:3:9741)
at http://localhost:8100/build/polyfills.js:3:6774
at t.invokeTask (http://localhost:8100/build/polyfills.js:3:15213)
at n.runTask (http://localhost:8100/build/polyfills.js:3:10390)
at a (http://localhost:8100/build/polyfills.js:3:5313)
at g (http://localhost:8100/build/polyfills.js:3:7133)
at l (http://localhost:8100/build/polyfills.js:3:6251)
at l (http://localhost:8100/build/polyfills.js:3:5937)
at http://localhost:8100/build/polyfills.js:3:6765
at t.invokeTask (http://localhost:8100/build/polyfills.js:3:15213)
at n.runTask (http://localhost:8100/build/polyfills.js:3:10390)
at a (http://localhost:8100/build/polyfills.js:3:5313)

Error 2 :

core.es5.js:1085 ERROR TypeError: Cannot read property 'scrollTo' of undefined at SummaryPage.scrollTo (http://localhost:8100/build/main.js:71046:88) at http://localhost:8100/build/main.js:71015:19 at http://localhost:8100/build/main.js:95387:36 at Array.forEach (native) at Events.publish (http://localhost:8100/build/main.js:95386:11) at SVGRectElement. (http://localhost:8100/build/main.js:138265:34) at SVGRectElement. (http://localhost:8100/build/main.js:55277:16) at t.invokeTask (http://localhost:8100/build/polyfills.js:3:15213) at Object.onInvokeTask (http://localhost:8100/build/main.js:4415:37) at t.invokeTask (http://localhost:8100/build/polyfills.js:3:15134) at n.runTask (http://localhost:8100/build/polyfills.js:3:10390) at SVGRectElement.invoke (http://localhost:8100/build/polyfills.js:3:16170)

1
Where is the button? You usually don't read from the DOM in Angular, this is why the renderer doesn't offer anything about reading from the DOM.Günter Zöchbauer
Actually, a button here is an item of Bar chart (SVG).You can think when the user clicks it then it has been called scrollTo() method.@GünterZöchbauerSampath
I still don't know how the button is related to the HTML above. I can't see anything related to SVG in your question. Therefore I don't know what information could be available to the button.Günter Zöchbauer
I don't think there is another way of reading offsetTop. There are only other ways to get the element reference.Günter Zöchbauer
Please see the update on my post @GünterZöchbauerSampath

1 Answers

0
votes

This might do what you want without reading from the DOM:

@Directive({
  selector: '[scrollIntoView]'
})
class ScrollIntoViewDirective {
  @Input() key:string;

  constructor(private elRef:ElementRef) {}

  srcrollTo() {
    this.elementRef.nativeElement.scrollIntoView();
  }
}
<ion-card *ngFor="let interval of intervals; let i = index" 
   [scrollIntoView]="interval.key">
@ViewChildren(ScrollIntoViewDirective) scrollIntoView:QueryList<ScrollIntoViewDirective>;

scrollTo(elementId: number) {
  this.scrollIntoView.toArray().find((s) => s.key == elementId).scrollTo();
}