#angular #angular-material2 #right-to-left
#angular #угловой-material2 #справа налево
Вопрос:
Я пытаюсь динамически изменять свой макет в соответствии с выбором языка пользователями и переключаться с LTR на RTL на лету.
Я использую Angular 2 rc6, материал 2.0.0-альфа.9-3
Похоже, что при загрузке страницы она отлично работает либо с rtl, либо с ltr. Однако, когда оно динамически изменяется из приложения (см. plunker), направление меняется, но сгенерированный элемент md-sidenav-content имеет неправильно рассчитанные поля справа и слева.
Копая дальше, мне удалось увидеть, что у объекта _dir есть EventEmitter, который должен отслеживать события изменения _dir и пересчитывать поля
@angular/material/sidenav/sidenav.js:
_dir.dirChange.subscribe(function () { return _this._validateDrawers(); });
Но это никогда не вызывается при динамическом изменении направления.
Хотя _dir сохраняет правильное значение при загрузке страницы в первый раз, будь то ltr или rtl.
Наконец, вот плунжер для демонстрации поведения:
http://plnkr.co/edit/o8lXWC?p=preview
Я подозреваю, что я неправильно использую _dir, но мне не удалось выяснить, как правильно это сделать.
Ответ №1:
Взгляните на директиву исходного кода Dir
@Input('dir') _dir: LayoutDirection = 'ltr';
Как вы можете видеть, вы меняете _dir
свойство вместо dir
установщика:
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
}
Вот ваш пример с плунжером
Если вы считаете, что это неправильное решение, проверьте это
Надеюсь, это поможет вам!
Комментарии:
1. Это выглядит многообещающе! Мне придется немного поиграть с этим, поскольку мое приложение не так упрощено, как plunker. Спасибо за подсказку, я сообщу о результатах.
2. Это сделало свое дело! Большое вам спасибо за то, что направили меня в правильном направлении.
Ответ №2:
Я пытался использовать атрибут выравнивания «end» и «start» для решения проблемы, но я не знаю, почему это невозможно. Я думаю, что возможное решение заключается в том, что вы немного «играете» с ngStyle и правым полем, как я показываю в следующем Plnkr
[ngStyle]="{'margin-right': move}"
Надеюсь, это может быть полезно.
Комментарии:
1. Дело в том, что это может сработать на поверхности (если у меня не так много контента на моей странице), но основная проблема заключается в том, что сгенерированный элемент md-sidenav-content, содержащий все, по-прежнему имеет неправильное левое поле, поэтому мой контент никогда не сможет охватить всю длину страницы. Смотрите скриншот того, что я имею в виду. ! Скриншот на полях
Ответ №3:
Я не уверен, что то, что я сделал с angular1, также работает с angular 2. Это просто добавление CSS:
md-sidenav {
left: initial;
right: 0;
}
md-sidenav.md-closed {
transform: translate3d(100%, 0, 0);
}
Чтобы теперь иметь его только для тех, у кого есть rtl-direction, было бы достаточно добавить класс / атрибут в тело, а затем выбрать только это.