Angular 4 TypeScript callaback用这个。在街区 [英] Angular 4 TypeScript callaback with this. in block

查看:76
本文介绍了Angular 4 TypeScript callaback用这个。在街区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个主题,我正在转换为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆