首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角4 TypeScript与此愈伤。在块

角4 TypeScript与此愈伤。在块
EN

Stack Overflow用户
提问于 2017-08-10 09:07:24
回答 3查看 471关注 0票数 0

我有一个主题,我正在转换成一个角4管理面板。主题有一个名为app.js的文件,其中包含一个类,我正试图将其转换为layout.component.ts In app.js,有几个代码块试图访问类之外的函数,但我已经将所有函数转换为layout.component.ts的方法;

代码语言:javascript
复制
$(window).resize(function(){
  this.resizePageContent();
});

运行这会产生Javascript错误。然而,在我的layout.component.ts上有一种方法应该在这种情况下使用。

代码语言:javascript
复制
this.resizePageContent is not a function

因此,我想知道哪种方法是最好的转换方式,这样就可以调用layout.component.ts方法了。这是我曾经尝试过的,但我不太确定这是否是最好的方法,以及为什么它会起作用。

代码语言:javascript
复制
$(window).resize(()=>{
      this.resizePageContent();
    });

用上述代码替换它之后,错误就消失了。

这是一个预览的app.js,它有超过700行的代码,所以我将无法粘贴到这里;

更新:

代码语言:javascript
复制
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

代码语言:javascript
复制
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如何输出这样的东西;

代码语言:javascript
复制
$(window).resize(()=>{
  this.resizePageContent();
});

...just来了解它是如何工作的。

EN

回答 3

Stack Overflow用户

发布于 2017-08-10 09:15:22

在您的例子中,使用以下代码

代码语言:javascript
复制
$(window).resize(()=>{
  this.resizePageContent();
});

是访问回调函数范围外的函数和变量的正确方法。

在使用时

代码语言:javascript
复制
function() {
  this.something;
}

“this”绑定到函数的作用域,而不是类的作用域。

在使用时

代码语言:javascript
复制
() => {
    this.something
}

即使用ecmascript 6箭头符号。Ecmascript 6看到了词法this的引入,在后一种情况下'this‘关键字指的是定义的类。

有关更多信息,请参见http://es6-features.org/#Lexicalthisthis

票数 2
EN

Stack Overflow用户

发布于 2017-08-10 09:16:43

如果您只需要在回调中执行委托或一行编码,请执行以下操作:

代码语言:javascript
复制
$(window).resize(()=> this.resizePageContent());

或者您也可以使用以下方法来调整页面内容的大小:

another question on stackoverflow to catch the window resizing event in Angular context

并使您的resizePageContent()方法侦听该事件。

票数 0
EN

Stack Overflow用户

发布于 2017-08-10 09:17:58

基于意见的问题,但就个人而言,最好的方法是使用类字段并分配箭头函数定义,并且在使用角时不使用jQuery:

代码语言:javascript
复制
window.addEventListener('resize', this.resizePageContent);

在您的类中,您应该定义如下方法:

代码语言:javascript
复制
private resizePageContent: EventListener = (event: UIEvent): void => {

};

这样做的最大优点是您可以删除事件侦听器的,如果使用匿名箭头函数,这是不可能的。

plunkr

另一种选择是使用bind(this)保留this上下文:

代码语言:javascript
复制
window.addEventListener('resize', this.resizePageContent.bind(this));

这样,您就不需要将回调分配给类的字段。但是使用bind可以创建该方法的副本,这使得删除事件侦听器变得更困难(并非不可能)。

您也可以直接使用@HostListener从组件内部收听它。事件的消除在内部是通过破坏部件的角度来完成的。

代码语言:javascript
复制
@HostListener('window:resize', ['$event'])
public resizePageContent(event: Event) {}

您收到错误的原因是因为您使用了function关键字。这将将this上下文更改为您要定义为回调的匿名函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45609186

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档