При разработке мультикультурного приложения Angular5 я структурировал класс, который содержит словарь (пользовательский класс ts) для хранения переводов. Когда пользователь меняет культуру, все, что с ней связано, должно измениться. Это работает, но… слишком много.
Поскольку я использую console.log каждый раз, когда вызывается метод, который получает правильное предложение в соответствии с выбранной культурой, я заметил, что если я просто нажимаю на текстовое поле, Angular обновляет все и, что непонятно, если я ничего не нажимаю вскоре после того, как просто оставьте фокус, снова angular все обновляет! Я знаю, что должно быть что-то связанное с ChangeDetectionStrategy, но я безуспешно пытался решить эту проблему.
Когда приложение вырастет, если браузеру придется каждый раз все перезагружать... какая проблема! Приложение выглядит так:
MainController.ts содержит все, что может быть полезно для компонентов, поэтому он передается в конструктор каждого компонента.
Главный контроллер выглядит так:
@Injectable()
export class MainController extends BaseClass {
private currentCulture: string;
private platformLocalizedSentencies: KeyedCollection<LocalizedString>;
класс LocalizedString выглядит так:
@Injectable()
export class LocalizedString extends BaseClass {
public DefaultText: string;
public IdTranslationIndex: number;
public Translations: KeyedCollection<string>;
constructor() {
super();
this.Translations = new KeyedCollection<string>();
}
public GetTranslation(culture: string) {
console.log('getting translation for ' + this.DefaultText + ' in culture ' + culture);
if (!this.Translations.ContainsKey(culture)) {
return '*' + this.DefaultText;
} else {
return this.Translations.Item(culture);
}
}
}
Теперь есть компонент (culture-selector.component.ts), который показывает флаги (changeDetection: ChangeDetectionStrategy.OnPush), и когда пользователь выбирает флаг, это происходит:
onCultureClick(menuItem: string) {
console.log(menuItem + ' clicked.');
this.mainController.CurrentCulture = menuItem; // this must be the thing which unleash the databinding on the other components I think and I hope
this.updateSelectedCultureUI(); // doesn't do anything special, just sets the right flag and culture name on the top of the control
this.mainController.trace(TraceType.Info, 'Culture ' + this.cultureName + ' clicked');
}
и компонент, где я заметил чертову дикость по привязке данных, компонент входа в систему:
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
})
export class LoginComponent extends BaseClass implements OnInit, AfterViewInit {
constructor(public mainController: MainController) {
super();
}
ngOnInit() {
this.usernamePlaceholder = this.mainController.PlatformLocalizedSentencies.Item('Username');
Теперь «usernamePlaceholder» используется в html следующим образом:
<mat-form-field style="width: 100%;">
<input matInput [placeholder]="usernamePlaceholder.GetTranslation(mainController.CurrentCulture)" [(ngModel)]="loginInput.username" (keypress)="eventHandler($event.keyCode, 'txtUsername')" #txtUsername>
</mat-form-field>
на следующем рисунке вы можете увидеть в окне консоли, что произойдет, если я просто щелкну текстовое поле имени пользователя .... Я очистил консоль перед щелчком. Что здесь происходит? Я потратил два дня, пытаясь понять... извините, это мое первое угловое приложение.. Я должен был начать с чего-то попроще :)
Вы можете видеть, что перевод имени пользователя получен ClassLibray.ts, в то время как другие предложения mainController.ts... это потому, что я пробовал разные способы, но тот же результат... в mainController код почти такой же:
.... и метод получения правильной строки
public GetPlatformSentence(key: string) {
console.log('getting translation for ' + key + ' in culture ' + this.CurrentCulture);
if (!this.PlatformLocalizedSentencies.ContainsKey(key)) {
return '[NOTRANSLATION]';
}
if (!this.PlatformLocalizedSentencies.Item(key).Translations.ContainsKey(this.CurrentCulture)) {
return '*' + this.PlatformLocalizedSentencies.Item(key).DefaultText;
} else {
return this.PlatformLocalizedSentencies.Item(key).Translations.Item(this.CurrentCulture);
}
}
Все равно спасибо