Angular2 material sidenav - 动态改变 rtl/ltr 方向
Angular2 material sidenav - changing rtl/ltr direction dynamically
我正在尝试根据用户的语言选择动态更改布局,并即时从 LTR 切换到 RTL。
我正在使用 Angular 2 rc6,material 2.0.0-alpha.9-3
看起来当页面加载时,它与 rtl 或 ltr 完美配合。
但是,当它从应用程序内部动态更改时(请参阅 plunker),方向会更改,但生成的元素 md-sidenav-content 的 margin-right 和 margin-left 计算错误。
进一步挖掘,我设法看到 _dir 对象有一个 eventEmitter,它应该监视 _dir 的更改事件并重新计算边距
@angular/material/sidenav/sidenav.js:
_dir.dirChange.subscribe(function () { return _this._validateDrawers(); });
但是在动态改变方向时从来没有调用过。
虽然,_dir 在第一次加载页面时保持正确的值,无论是 ltr 还是 rtl。
最后,这里有一个 plunker 来演示该行为:
http://plnkr.co/edit/o8lXWC?p=preview
我怀疑我没有正确使用 _dir,但没有弄清楚正确的方法。
我一直在尝试使用"end"和"start"对齐属性来解决问题,但不知道为什么不行。
我认为一个可能的解决方案是你 "play" 有点像我在下面的 Plnkr
中展示的 NgStyle 和 margin-right
[ngStyle]="{'margin-right': move}"
希望这可能有用。
查看源代码Dir
指令
@Input('dir') _dir: LayoutDirection = 'ltr';
如您所见,您正在更改 _dir
属性 而不是 dir
setter:
set dir(v: LayoutDirection) {
let old = this._dir;
this._dir = v;
if (old != this._dir) {
this.dirChange.emit(null);
}
}
所以我认为你的解决方案应该是这样的:
查看
<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
属性。
还有一张纸条:
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 Example
如果您认为这是错误的决定,请查看此
希望对您有所帮助!
我不确定我对 angular1 所做的是否也适用于 angular2。
那只是添加一个 CSS:
md-sidenav {
left: initial;
right: 0;
}
md-sidenav.md-closed {
transform: translate3d(100%, 0, 0);
}
现在只为那些有 rtl 方向的人提供它,在正文中添加一个 class/attribute 然后只选择它就足够了。
我正在尝试根据用户的语言选择动态更改布局,并即时从 LTR 切换到 RTL。
我正在使用 Angular 2 rc6,material 2.0.0-alpha.9-3
看起来当页面加载时,它与 rtl 或 ltr 完美配合。 但是,当它从应用程序内部动态更改时(请参阅 plunker),方向会更改,但生成的元素 md-sidenav-content 的 margin-right 和 margin-left 计算错误。
进一步挖掘,我设法看到 _dir 对象有一个 eventEmitter,它应该监视 _dir 的更改事件并重新计算边距
@angular/material/sidenav/sidenav.js:
_dir.dirChange.subscribe(function () { return _this._validateDrawers(); });
但是在动态改变方向时从来没有调用过。 虽然,_dir 在第一次加载页面时保持正确的值,无论是 ltr 还是 rtl。
最后,这里有一个 plunker 来演示该行为:
http://plnkr.co/edit/o8lXWC?p=preview
我怀疑我没有正确使用 _dir,但没有弄清楚正确的方法。
我一直在尝试使用"end"和"start"对齐属性来解决问题,但不知道为什么不行。 我认为一个可能的解决方案是你 "play" 有点像我在下面的 Plnkr
中展示的 NgStyle 和 margin-right[ngStyle]="{'margin-right': move}"
希望这可能有用。
查看源代码Dir
指令
@Input('dir') _dir: LayoutDirection = 'ltr';
如您所见,您正在更改 _dir
属性 而不是 dir
setter:
set dir(v: LayoutDirection) {
let old = this._dir;
this._dir = v;
if (old != this._dir) {
this.dirChange.emit(null);
}
}
所以我认为你的解决方案应该是这样的:
查看
<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
属性。
还有一张纸条:
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 Example
如果您认为这是错误的决定,请查看此
希望对您有所帮助!
我不确定我对 angular1 所做的是否也适用于 angular2。 那只是添加一个 CSS:
md-sidenav {
left: initial;
right: 0;
}
md-sidenav.md-closed {
transform: translate3d(100%, 0, 0);
}
现在只为那些有 rtl 方向的人提供它,在正文中添加一个 class/attribute 然后只选择它就足够了。