1

im using angular4 to implement my administration panel of my site. for ui, im using a template that i downloaded from the internet for free. this template have a datatable feature that shows data in a very nice way and gives me ability to search, sort and pagination. im loading this table in an angular component called organization-list.component that is :

    import { Component, AfterViewChecked } from "@angular/core";
    import { Script } from "../../shared/services/scriptLoader.service";

    @Component({
      selector: "organization-list",
      templateUrl: "./organization-list.component.html"
    })
    export class OrganizationListComponent implements AfterViewChecked {
      constructor(private script: Script) {

      }

      ngAfterViewChecked() {
        this.script.loadScript("assets/datatables/jquery.dataTables.min.js");
        this.script.loadScript("assets/datatables/dataTables.bootstrap.js");
      }
    }

for loading features of this form there are two scripts: jquery.dataTables.min.js and jquery.dataTables.min.js that i want theme to loaded just in this component(page). so i used this function to load them:

import { Injectable } from '@angular/core';

declare var document: any;

@Injectable()
export class Script {

  loadScript(path: string) {
    //load script
    return new Promise((resolve, reject) => {
      let script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = path;
      if (script.readyState) {  //IE
        script.onreadystatechange = () => {
          if (script.readyState === "loaded" || script.readyState === "complete") {
            script.onreadystatechange = null;
            resolve({ loaded: true, status: 'Loaded' });
          }
        };
      } else {  //Others
        script.onload = () => {
          resolve({ loaded: true, status: 'Loaded' });
        };
      };
      script.onerror = (error: any) => resolve({ loaded: false, status: 'Loaded' });
      document.getElementsByTagName('head')[0].appendChild(script);
    });
  }
}

and this works good. in scripts i mentioned the is a function called datatable that must be called in the end of html page like this:

<script>
  $(document).ready(function() {
    $('#datatable').dataTable();
  });
</script>

the problem is that i want to call this peace of code every time this page loads (i use angular routing so page dosnt load entirely). what is the solution ? thanks.

4
  • there are a lot of other datatables. please avoid using jQuery Commented Nov 30, 2017 at 23:12
  • @Aravind my template is writen with jquery. what can i do? Commented Nov 30, 2017 at 23:17
  • 1
    your approach is wrong. Whereever you use the datatable, you should run the code there. I assume your code separated into components, call the $('#datatable').dataTable(); part at ngOnInit lifecycle hook. Commented Dec 1, 2017 at 0:54
  • @Aravind why should he avoid using jQuery ? I am just curious . Is there any cons using jQuery ? Commented Dec 1, 2017 at 16:33

1 Answer 1

2

You are loading the scripts in an unspecified order and you are not caching them which is bad for performance and makes their behavior unpredictable.

Leave it to your loader or bundler. If you are using SystemJS or Webpack 3*, then simply

import 'assets/datatables/jquery.dataTables.min.js';
import 'assets/datatables/dataTables.bootstrap.js';

Use a view child to access the element that the datatable is applied to.

import {Component, ViewChild} from '@angular/core';
import $ from 'jquery';
import 'assets/datatables/jquery.dataTables.min.js';
import 'assets/datatables/dataTables.bootstrap.js';


@Component({
  template: '<div #datatable></div>'
}) export default class {
  @ViewChild('datatable') datatable: Element;

  ngAfterViewInit() {
    $(this.datatable).datatable();
  }

}

Get rid of the script tag containing the $('#datatable').datatable() completely.

Note that at the time of this writing, the Angular CLI is based on Webpack.

Sign up to request clarification or add additional context in comments.

4 Comments

thanks for your answer. i added script to angular-cli.json and they are liked but when i call .datatable as you told, i give $(...).datatable is not a function error
Don't do that. You want to install your dependencies using a package manager. You also want to eliminate global variables.
according to your comment i have not any other way except using systemjs or webpack?
The CLI is built on top of Webpack. Technically you could use other tools as well.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.