Issue
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.
Solution
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.
Answered By - Aluan Haddad
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.