我有一个主题,我正在转换成一个角4管理面板。主题有一个名为app.js的文件,其中包含一个类,我正试图将其转换为layout.component.ts In app.js,有几个代码块试图访问类之外的函数,但我已经将所有函数转换为layout.component.ts的方法;
$(window).resize(function(){
this.resizePageContent();
});运行这会产生Javascript错误。然而,在我的layout.component.ts上有一种方法应该在这种情况下使用。
this.resizePageContent is not a function因此,我想知道哪种方法是最好的转换方式,这样就可以调用layout.component.ts方法了。这是我曾经尝试过的,但我不太确定这是否是最好的方法,以及为什么它会起作用。
$(window).resize(()=>{
this.resizePageContent();
});用上述代码替换它之后,错误就消失了。
这是一个预览的app.js,它有超过700行的代码,所以我将无法粘贴到这里;
更新:
var App = function() {
/* Helper variables - set in uiInit() */
var page, pageContent, header, footer, sidebar, sScroll, sidebarAlt, sScrollAlt;
/* Initialization UI Code */
var uiInit = function() {...};
/* Page Loading functionality */
var pageLoading = function(){..};
/* Gets window width cross browser */
var getWindowWidth = function(){...};
/* Sidebar Navigation functionality */
var handleNav = function() {..};
/* Scrolls the page (static layout) or the sidebar scroll element (fixed header/sidebars layout) to a specific position - Used when a submenu opens */
var handlePageScroll = function(sElem, sHeightDiff, sSpeed) {...};
/* Sidebar Functionality */
var handleSidebar = function(mode, extra) {...};
/* Resize #page-content to fill empty space if exists */
var resizePageContent = function() {...};
/* Interactive blocks functionality */
var interactiveBlocks = function() {...};
/* Scroll to top functionality */
var scrollToTop = function() {...};
/* Demo chat functionality (in sidebar) */
var chatUi = function() {...};
/* Template Options, change features functionality */
var templateOptions = function() {...};
/* Datatables basic Bootstrap integration (pagination integration included under the Datatables plugin in plugins.js) */
var dtIntegration = function() {...};
/* Print functionality - Hides all sidebars, prints the page and then restores them (To fix an issue with CSS print styles in webkit browsers) */
var handlePrint = function() {...};
return {
init: function() {
uiInit(); // Initialize UI Code
pageLoading(); // Initialize Page Loading
},
sidebar: function(mode, extra) {
handleSidebar(mode, extra); // Handle sidebars - access functionality from everywhere
},
datatables: function() {
dtIntegration(); // Datatables Bootstrap integration
},
pagePrint: function() {
handlePrint(); // Print functionality
}
};
}();
/* Initialize app when page loads */
$(function(){ App.init(); });这是我的layout.component.ts;
import { Component, OnInit } from '@angular/core';
declare var jQuery: any;
declare var $: any;
declare var window: any;
declare var document: any;
declare var Cookies: any;
@Component({
selector: 'app-layout',
templateUrl: './layout.component.html',
styleUrls: ['./layout.component.css']
})
export class LayoutComponent implements OnInit {
public page;
public pageContent;
public header;
public footer;
public sidebar;
public sScroll;
public sidebarAlt;
public sScrollAlt;
constructor() { }
ngOnInit() {
this.init();
}
uiInit (): void {...}
pageLoading (): void {...}
getWindowWidth (): any {...}
handleNav (): any {...}
handlePageScroll (sElem, sHeightDiff, sSpeed): void {...}
handleSidebar (mode, extra?:any): any {
if (mode === 'init') {
// Init sidebars scrolling functionality
this.handleSidebar('sidebar-scroll');
this.handleSidebar('sidebar-alt-scroll');
// Close the other sidebar if we hover over a partial one
// In smaller screens (the same applies to resized browsers) two visible sidebars
// could mess up our main content (not enough space), so we hide the other one :-)
$('.sidebar-partial #sidebar')
.mouseenter(function(){ this.handleSidebar('close-sidebar-alt'); });
$('.sidebar-alt-partial #sidebar-alt')
.mouseenter(function(){ this.handleSidebar('close-sidebar'); });
} else {
var windowW = this.getWindowWidth();
if (mode === 'toggle-sidebar') {
if ( windowW > 991) { // Toggle main sidebar in large screens (> 991px)
this.page.toggleClass('sidebar-visible-lg');
if (this.page.hasClass('sidebar-mini')) {
this.page.toggleClass('sidebar-visible-lg-mini');
}
if (this.page.hasClass('sidebar-visible-lg')) {
this.handleSidebar('close-sidebar-alt');
}
// If 'toggle-other' is set, open the alternative sidebar when we close this one
if (extra === 'toggle-other') {
if (!this.page.hasClass('sidebar-visible-lg')) {
this.handleSidebar('open-sidebar-alt');
}
}
} else { // Toggle main sidebar in small screens (< 992px)
this.page.toggleClass('sidebar-visible-xs');
if (this.page.hasClass('sidebar-visible-xs')) {
this.handleSidebar('close-sidebar-alt');
}
}
// Handle main sidebar scrolling functionality
this.handleSidebar('sidebar-scroll');
}
else if (mode === 'toggle-sidebar-alt') {
if ( windowW > 991) { // Toggle alternative sidebar in large screens (> 991px)
this.page.toggleClass('sidebar-alt-visible-lg');
if (this.page.hasClass('sidebar-alt-visible-lg')) {
this.handleSidebar('close-sidebar');
}
// If 'toggle-other' is set open the main sidebar when we close the alternative
if (extra === 'toggle-other') {
if (!this.page.hasClass('sidebar-alt-visible-lg')) {
this.handleSidebar('open-sidebar');
}
}
} else { // Toggle alternative sidebar in small screens (< 992px)
this.page.toggleClass('sidebar-alt-visible-xs');
if (this.page.hasClass('sidebar-alt-visible-xs')) {
this.handleSidebar('close-sidebar');
}
}
}
else if (mode === 'open-sidebar') {
if ( windowW > 991) { // Open main sidebar in large screens (> 991px)
if (this.page.hasClass('sidebar-mini')) { this.page.removeClass('sidebar-visible-lg-mini'); }
this.page.addClass('sidebar-visible-lg');
} else { // Open main sidebar in small screens (< 992px)
this.page.addClass('sidebar-visible-xs');
}
// Close the other sidebar
this.handleSidebar('close-sidebar-alt');
}
else if (mode === 'open-sidebar-alt') {
if ( windowW > 991) { // Open alternative sidebar in large screens (> 991px)
this.page.addClass('sidebar-alt-visible-lg');
} else { // Open alternative sidebar in small screens (< 992px)
this.page.addClass('sidebar-alt-visible-xs');
}
// Close the other sidebar
this.handleSidebar('close-sidebar');
}
else if (mode === 'close-sidebar') {
if ( windowW > 991) { // Close main sidebar in large screens (> 991px)
this.page.removeClass('sidebar-visible-lg');
if (this.page.hasClass('sidebar-mini')) { this.page.addClass('sidebar-visible-lg-mini'); }
} else { // Close main sidebar in small screens (< 992px)
this.page.removeClass('sidebar-visible-xs');
}
}
else if (mode === 'close-sidebar-alt') {
if ( windowW > 991) { // Close alternative sidebar in large screens (> 991px)
this.page.removeClass('sidebar-alt-visible-lg');
} else { // Close alternative sidebar in small screens (< 992px)
this.page.removeClass('sidebar-alt-visible-xs');
}
}
else if (mode === 'sidebar-scroll') { // Handle main sidebar scrolling
if (this.page.hasClass('sidebar-mini') && this.page.hasClass('sidebar-visible-lg-mini') && (windowW > 991)) { // Destroy main sidebar scrolling when in mini sidebar mode
if (this.sScroll.length && this.sScroll.parent('.slimScrollDiv').length) {
this.sScroll
.slimScroll({destroy: true});
this.sScroll
.attr('style', '');
}
}
else if ((this.page.hasClass('header-fixed-top') || this.page.hasClass('header-fixed-bottom'))) {
var sHeight = $(window).height();
if (this.sScroll.length && (!this.sScroll.parent('.slimScrollDiv').length)) { // If scrolling does not exist init it..
this.sScroll
.slimScroll({
height: sHeight,
color: '#fff',
size: '3px',
touchScrollStep: 100
});
// Handle main sidebar's scrolling functionality on resize or orientation change
var sScrollTimeout;
$(window).on('resize orientationchange', function(){
clearTimeout(sScrollTimeout);
sScrollTimeout = setTimeout(function(){
this.handleSidebar('sidebar-scroll');
}, 150);
});
}
else { // ..else resize scrolling height
this.sScroll
.add(this.sScroll.parent())
.css('height', sHeight);
}
}
}
else if (mode === 'sidebar-alt-scroll') { // Init alternative sidebar scrolling
if ((this.page.hasClass('header-fixed-top') || this.page.hasClass('header-fixed-bottom'))) {
var sHeightAlt = $(window).height();
if (this.sScrollAlt.length && (!this.sScrollAlt.parent('.slimScrollDiv').length)) { // If scrolling does not exist init it..
this.sScrollAlt
.slimScroll({
height: sHeightAlt,
color: '#fff',
size: '3px',
touchScrollStep: 100
});
// Resize alternative sidebar scrolling height on window resize or orientation change
var sScrollAltTimeout;
$(window).on('resize orientationchange', function(){
clearTimeout(sScrollAltTimeout);
sScrollAltTimeout = setTimeout(function(){
this.handleSidebar('sidebar-alt-scroll');
}, 150);
});
}
else { // ..else resize scrolling height
this.sScrollAlt
.add(this.sScrollAlt.parent())
.css('height', sHeightAlt);
}
}
}
}
return false;
}
resizePageContent (): void {...}
interactiveBlocks (): void {...}
scrollToTop (): any{...}
chatUi (): any {...}
templateOptions (): void {...}
dtIntegration (): any {...}
handlePrint (): void {...}
//Methods from original object
init (): void {
this.uiInit(); // Initialize UI Code
this.pageLoading(); // Initialize Page Loading
}
//Originally sidebar
CallhandleSidebar(mode, extra): void {
this.handleSidebar(mode, extra); // Handle sidebars - access functionality from everywhere
}
datatables() :void {
this.dtIntegration(); // Datatables Bootstrap integration
}
pagePrint (): void {
this.handlePrint(); // Print functionality
}
}另外,你能给我一个例子,说明TypeScript如何输出这样的东西;
$(window).resize(()=>{
this.resizePageContent();
});...just来了解它是如何工作的。
发布于 2017-08-10 09:15:22
在您的例子中,使用以下代码
$(window).resize(()=>{
this.resizePageContent();
});是访问回调函数范围外的函数和变量的正确方法。
在使用时
function() {
this.something;
}“this”绑定到函数的作用域,而不是类的作用域。
在使用时
() => {
this.something
}即使用ecmascript 6箭头符号。Ecmascript 6看到了词法this的引入,在后一种情况下'this‘关键字指的是定义的类。
有关更多信息,请参见http://es6-features.org/#Lexicalthis和this。
发布于 2017-08-10 09:16:43
如果您只需要在回调中执行委托或一行编码,请执行以下操作:
$(window).resize(()=> this.resizePageContent());或者您也可以使用以下方法来调整页面内容的大小:
another question on stackoverflow to catch the window resizing event in Angular context
并使您的resizePageContent()方法侦听该事件。
发布于 2017-08-10 09:17:58
基于意见的问题,但就个人而言,最好的方法是使用类字段并分配箭头函数定义,并且在使用角时不使用jQuery:
window.addEventListener('resize', this.resizePageContent);在您的类中,您应该定义如下方法:
private resizePageContent: EventListener = (event: UIEvent): void => {
};这样做的最大优点是您可以删除事件侦听器的,如果使用匿名箭头函数,这是不可能的。
另一种选择是使用bind(this)保留this上下文:
window.addEventListener('resize', this.resizePageContent.bind(this));这样,您就不需要将回调分配给类的字段。但是使用bind可以创建该方法的副本,这使得删除事件侦听器变得更困难(并非不可能)。
您也可以直接使用@HostListener从组件内部收听它。事件的消除在内部是通过破坏部件的角度来完成的。
@HostListener('window:resize', ['$event'])
public resizePageContent(event: Event) {}您收到错误的原因是因为您使用了function关键字。这将将this上下文更改为您要定义为回调的匿名函数。
https://stackoverflow.com/questions/45609186
复制相似问题