Angular2 material sidenav - 动态改变 rtl/ltr 方向 [英] Angular2 material sidenav - changing rtl/ltr direction dynamically

查看:20
本文介绍了Angular2 material sidenav - 动态改变 rtl/ltr 方向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据用户的语言选择动态更改布局,并即时从 LTR 切换到 RTL.

I'm trying to change my layout dynamically according to users' language selection and switch from LTR to RTL on the fly.

我使用的是 Angular 2 rc6,材质 2.0.0-alpha.9-3

I'm using Angular 2 rc6, material 2.0.0-alpha.9-3

看起来当页面加载时,它与 rtl 或 ltr 完美配合.但是,当它从应用程序内部动态更改时(请参阅 plunker),方向会发生变化,但生成的元素 md-sidenav-content 会计算错误的 margin-right 和 margin-left.

It looks like when the page is loaded, it works perfectly with either rtl or ltr. However, when it's changed dynamically from within the app (see plunker), the direction changes but the generated element md-sidenav-content has a miscalculated margin-right and margin-left.

进一步挖掘,我设法看到 _dir 对象有一个 eventEmitter,它应该监视 _dir 的更改事件并重新计算边距

Digging further, I managed to see that the _dir object has an eventEmitter that should watch for on change events of _dir and recalculate the margins

@angular/material/sidenav/sidenav.js:

@angular/material/sidenav/sidenav.js:

_dir.dirChange.subscribe(function () { return _this._validateDrawers(); });

但是在动态改变方向时它永远不会被调用.虽然,_dir 在第一次加载页面时保存了正确的值,无论是 ltr 还是 rtl.

But it's never called when changing the direction dynamically. Although, _dir holds the correct value when page is being loaded for the first time, whether its ltr or rtl.

最后,这是一个演示行为的plunker:

Finally, here's a plunker to demonstrate the behaviour:

http://plnkr.co/edit/o8lXWC?p=preview

我怀疑我没有正确使用 _dir 但没有设法找出正确的方法.

I suspect I'm not using _dir correctly but not managed to figure out what's the right way to do it.

推荐答案

看源码Dir指令

@Input('dir') _dir: LayoutDirection = 'ltr';

  • https://github.com/angular/material2/blob/2.0.0-alpha.9/src/lib/core/rtl/dir.ts#L19-L43
  • 如您所见,您正在更改 _dir 属性而不是 dir setter:

    As you can see you're changing _dir property instead of dir setter:

    set dir(v: LayoutDirection) {
      let old = this._dir;
      this._dir = v;
      if (old != this._dir) {
        this.dirChange.emit(null);
      }
    }
    

    所以我认为你的解决方案应该是这样的:

    So i think your solution should be like:

    查看

    <md-sidenav-layout fullscreen dir="ltr" #root="$implicit">
    
    <select #langSelect (change)="changeLang(langSelect.value, root)">
    

    组件

    changeLang(lang, root: Dir) {
      this.translate.use(lang);
      root.dir = lang == "fr" ? "rtl" : "ltr";
    }
    

    这样您就可以省略组件上的 direction: string 属性.

    This way you can omit direction: string property on your component.

    还有一个注意事项:

    translate: TranslateService; //it's redundant `private translate: TranslateService` does it
    direction: string; // omit it
    
    constructor(private translate: TranslateService) {
      this.direction = "ltr"; // omit it
      translate.addLangs(["en", "fr"]);
      translate.setDefaultLang('en');
    
      let browserLang = translate.getBrowserLang();
      translate.use(browserLang.match(/en|fr/) ? browserLang : 'en');
      this.translate = translate; // it's redundant
    }
    

    这是您的 Plunker 示例

    Here's your Plunker Example

    如果您认为这是错误的决定,请检查此

    If you think that this is the wrong decision then check this

    希望对你有帮助!

    这篇关于Angular2 material sidenav - 动态改变 rtl/ltr 方向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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