Angular 4 TypeScript callaback用这个。在街区 [英] Angular 4 TypeScript callaback with this. in block
问题描述
我有一个主题,我正在转换为Angular 4管理面板。该主题有一个名为app.js的文件,其中包含一个类,我试图将其转换为我的 layout.component.ts
在app.js中有几个代码块可供尝试访问类外部的函数,但我已将所有函数转换为我的 layout.component.ts
;
<$ p的方法$ p>
$(window).resize(function(){
this.resizePageContent();
});
运行此操作会出现Javascript错误。但是在我的 layout.component.ts
上有一个方法,在这种情况下应该使用。;
this.resizePageContent不是函数
所以我想知道哪个是转换它的最佳方法是调用 layout.component.ts
方法。这是我尝试过但我不确定这是否是最好的方法以及它的工作原理。
$(window).resize(()=> {
this.resizePageContent();
});
用上面的代码替换后,错误消失了。
这是app.js的预览它有超过700行代码,所以我不能在这里粘贴所有内容;
更新:
var App = function(){
/ *帮助变量 - 在uiInit中设置()* /
var page,pageContent,header,footer,sidebar,sScroll,sidebarAlt,sScrollAlt;
/ *初始化UI代码* /
var uiInit = function(){...};
/ *页面加载功能* /
var pageLoading = function(){..};
/ *获取窗口宽度跨浏览器* /
var getWindowWidth = function(){...};
/ *边栏导航功能* /
var handleNav = function(){..};
/ *将页面(静态布局)或侧边栏滚动元素(固定标题/侧边栏布局)滚动到特定位置 - 在子菜单打开时使用* /
var handlePageScroll = function( sElem,sHeightDiff,sSpeed){...};
/ *边栏功能* /
var handleSidebar = function(mode,extra){...};
/ *调整#page-content的大小以填充空格(如果存在)* /
var resizePageContent = function(){...};
/ *交互式块功能* /
var interactiveBlocks = function(){...};
/ *滚动到顶部功能* /
var scrollToTop = function(){...};
/ *演示聊天功能(在侧边栏中)* /
var chatUi = function(){...};
/ *模板选项,更改功能功能* /
var templateOptions = function(){...};
/ * Datatables基本的Bootstrap集成(plugins.js中Datatables插件下包含的分页集成)* /
var dtIntegration = function(){...};
/ *打印功能 - 隐藏所有侧边栏,打印页面然后恢复它们(修复webkit浏览器中CSS打印样式的问题)* /
var handlePrint = function(){ ...};
return {
init:function(){
uiInit(); //初始化UI代码
pageLoading(); //初始化页面加载
},
侧栏:函数(模式,额外){
handleSidebar(mode,extra); //处理侧边栏 - 从任何地方访问功能
},
datatables:function(){
dtIntegration(); // Datatables Bootstrap集成
},
pagePrint:function(){
handlePrint(); //打印功能
}
};
}();
/ *页面加载时初始化app * /
$(function(){App.init();});
这是我的 layout.component.ts
;
从'@ angular / core'导入{Component,OnInit};
声明var jQuery:any;
声明var $:any;
声明var窗口:any;
声明var文档:any;
声明var Cookies:any;
@Component({
selector:'app-layout',
templateUrl:'。/ layout.component.html',
styleUrls:['./ layout.component.css']
})
导出类LayoutComponent实现OnInit {
公共页面;
public pageContent;
公共标题;
公共页脚;
公共边栏;
public sScroll;
public sidebarAlt;
public sScrollAlt;
constructor(){}
ngOnInit(){
this.init();
}
uiInit():void {...}
pageLoading():void {...}
getWindowWidth ():任何{...}
handleNav():任何{...}
handlePageScroll(sElem,sHeightDiff,sSpeed):void {...}
handleSidebar(模式,额外?:任何):任何{
if(mode ==='init'){
// Init sidebars滚动功能
this .handleSidebar( '侧栏滚动');
this.handleSidebar('sidebar-alt-scroll');
//如果我们将鼠标悬停在部分一个
上,请关闭另一个侧边栏//在较小的屏幕中(同样适用于调整大小的浏览器)两个可见的边栏
//可能会搞砸我们的主要内容(空间不够),所以我们隐藏另一个:-)
$('。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){//在大屏幕中切换主侧边栏(> 991px)
this.page.toggleClass( '侧栏可见-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');
}
//如果设置了'toggle-other',当我们关闭这个时,打开备用边栏
if(extra ==='toggle-other'){
if(!this.page.hasClass('sidebar-visible-lg')){
this.handleSidebar('open-sidebar-alt');
}
}
} else {//在小屏幕中切换主侧边栏(< 992px)
this.page.toggleClass('sidebar-visible-xs');
if(this.page.hasClass('sidebar-visible-xs')){
this.handleSidebar('close-sidebar-alt');
}
}
//处理主侧边栏滚动功能
this.handleSidebar('sidebar-scroll');
}
else if(mode ==='toggle-sidebar-alt'){
if(windowW> 991){//在大屏幕中切换替代边栏(> 991px)
this.page.toggleClass('sidebar-alt-visible-lg');
if(this.page.hasClass('sidebar-alt-visible-lg')){
this.handleSidebar('close-sidebar');
}
//如果设置'toggle-other',当我们关闭替代
if(extra ==='toggle-other'){$时,打开主侧边栏b $ b if(!this.page.hasClass('sidebar-alt-visible-lg')){
this.handleSidebar('open-sidebar');
}
}
} else {//在小屏幕中切换替代边栏(< 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){//打开主侧边栏在大屏幕(> 991px)
if(this.page.hasClass('sidebar-mini')){this.page.removeClass('sidebar-visible-lg-mini'); }
this.page.addClass('sidebar-visible-lg');
} else {//在小屏幕中打开主侧边栏(< 992px)
this.page.addClass('sidebar-visible-xs');
}
//关闭另一个侧边栏
this.handleSidebar('close-sidebar-alt');
}
else if(mode ==='open-sidebar-alt'){
if(windowW> 991){//在大屏幕中打开备用侧边栏(> 991px)
this.page.addClass('sidebar-alt-visible-lg');
} else {//在小屏幕中打开备用侧边栏(< 992px)
this.page.addClass('sidebar-alt-visible-xs');
}
//关闭另一个边栏
this.handleSidebar('close-sidebar');
}
else if(mode ==='close-sidebar'){
if(windowW> 991){//在大屏幕中关闭主侧边栏(> 991px)
this.page.removeClass('sidebar-visible-lg');
if(this.page.hasClass('sidebar-mini')){this.page.addClass('sidebar-visible-lg-mini'); }
} else {//在小屏幕中关闭主侧边栏(< 992px)
this.page.removeClass('sidebar-visible-xs');
}
}
else if(mode ==='close-sidebar-alt'){
if(windowW> 991){//关闭大屏幕中的替代侧边栏(> 991px)
this.page.removeClass('sidebar-alt-visible-lg');
} else {//在小屏幕中关闭替代边栏(< 992px)
this.page.removeClass('sidebar-alt-visible-xs');
}
}
else if(mode ==='sidebar-scroll'){//处理主侧边栏滚动
if(this.page.hasClass('sidebar-mini) ')&& this.page.hasClass('sidebar-visible-lg-mini')&&(windowW> 991)){//在迷你侧边栏模式下销毁主侧边栏滚动
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)){//如果滚动不存在则init .. .. b $ b this.sScroll
.slimScroll({
height:sHeight,
color:'#fff',
size:'3px',
touchScrollStep:100
});
//在调整大小或方向改变时处理主侧边栏的滚动功能
var sScrollTimeout;
$(窗口).on('resize orientationchange',function(){
clearTimeout(sScrollTimeout);
sScrollTimeout = setTimeout(function(){
this.handleSidebar('sidebar-scroll');
},150);
});
}
else {// ..请调整大小滚动高度
this.sScroll
.add(this.sScroll.parent())
.css('height ',sHeight);
}
}
}
否则if(mode ==='sidebar-alt-scroll'){//初始替代侧边栏滚动
if((这。 page.hasClass('header-fixed-top')|| this.page.hasClass('header-fixed-bottom'))){
var sHeightAlt = $(window).height();
if(this.sScrollAlt.length&&(!this.sScrollAlt.parent('。slimScrollDiv')。length)){//如果滚动不存在则init .. .. b $ b this.sScrollAlt
.slimScroll({
height:sHeightAlt,
color:'#fff',
size:'3px',
touchScrollStep:100
});
//在窗口调整大小或方向更改时调整替代侧边栏滚动高度
var sScrollAltTimeout;
$(窗口).on('resize orientationchange',function(){
clearTimeout(sScrollAltTimeout);
sScrollAltTimeout = setTimeout(function(){
this.handleSidebar('sidebar-alt-scroll');
},150);
});
}
else {// ..请调整大小滚动高度
this.sScrollAlt
.add(this.sScrollAlt.parent())
.css('height ',sHeightAlt);
}
}
}
}
返回false;
}
resizePageContent():void {...}
interactiveBlocks():void {...}
scrollToTop ():任何{...}
chatUi():任何{...}
templateOptions():void {...}
dtIntegration():任何{...}
handlePrint():void {...}
//原始对象的方法
init():void {
this.uiInit(); //初始化UI代码
this.pageLoading(); //初始化页面加载
}
//最初是侧边栏
CallhandleSidebar(模式,额外):void {
this.handleSidebar(mode,extra); //处理侧边栏 - 从任何地方访问功能
}
datatables():void {
this.dtIntegration(); // Datatables Bootstrap集成
}
pagePrint():void {
this.handlePrint(); //打印功能
}
}
你也可以吗?给我一个例子,说明TypeScript可能会输出这样的东西;
$(window).resize(()=> {
this.resizePageContent();
});
...只是为了了解它是如何工作的。
在您的情况下,使用代码
$ (窗口).resize(()=> {
this.resizePageContent();
});
是访问回调函数范围之外的函数和变量的正确方法。
使用时
function(){
this.something;
}
'this'绑定到函数的范围,而不是该等。
使用时
()=> {
this.something
}
使用ecmascript 6箭头表示法。 Ecmascript 6看到了词汇的引入,在后一种情况下,'this'关键字指的是定义的类。
有关更多信息,请参阅 http://es6-features.org/#Lexicalthis 和 https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_this 。
I have a theme that I am converting into an Angular 4 admin panel. The theme has a file called app.js containing a class which I am trying to convert into my layout.component.ts
In app.js there are several blocks of code that try to access functions outside the class but I have converted all functions into methods of my layout.component.ts
;
$(window).resize(function(){
this.resizePageContent();
});
Running this gives a Javascript error. However there is a method on my layout.component.ts
that should be used in this case.;
this.resizePageContent is not a function
So I am wondering which is the best way to convert this such that the layout.component.ts
method is called instead. This is what I have tried but I am not so sure whether this is the best way to do it and why it works.
$(window).resize(()=>{
this.resizePageContent();
});
After replacing it with the above code the errors have disappeared.
This is a preview of app.js It has over 700 lines of code so I will not be able to paste it all here;
Update:
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(); });
This is my 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
}
}
Also could you give me an example of how TypeScript might output something like this;
$(window).resize(()=>{
this.resizePageContent();
});
...just to get a good idea of how it works.
In your case, using the code
$(window).resize(()=>{
this.resizePageContent();
});
is the correct way for accessing functions and variables outside of the scope of the callback function.
When using
function() {
this.something;
}
the 'this' is bound to the scope of the function, rather than of the class.
When using
() => {
this.something
}
that is using ecmascript 6 arrow notation. Ecmascript 6 sees the introduction of the lexical this, where in the latter case the 'this' keyword refers to the class defined.
For more information see http://es6-features.org/#Lexicalthis and https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_this .
这篇关于Angular 4 TypeScript callaback用这个。在街区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!