为什么在 Angular 5 中获取焦点 Trigs 数据绑定?



开发多元文化的Angular5应用程序 我构建了一个包含字典(自定义 ts 类)的类来保存翻译。当用户更改区域性时,与之相关的任何内容都必须更改。它有效,但是....太多了

由于我习惯于控制台.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 获取。这是因为我尝试了不同的方法,但结果相同......在主控制器中,代码几乎相同:

....以及检索正确字符串的方法

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);
}
}

无论如何谢谢你

这是发生的事情

好的伙计们,我已经尝试了任何东西,但没有任何成功。角绑定是...太迂腐了:-) 我能够实现的最佳结果是第一次用户交互时的刷新。所以我不得不在每次刷新所有内容(这太多了)或用户单击某个地方强制绑定刷新时立即刷新之间进行选择(这就是我能够使用 ChangeDetectionStrategy 设置和一些附加代码获得的)。

所以我使用消息服务解决了(仅用于多切立即绑定)。每个组件都订阅并要求一个通用的 maicontroller 在区域性更改时更新与区域性相关的任何内容。当然,我需要编写更多的代码,但在用户体验,响应能力和CPU负载方面的结果非常非常好。此外,每个组件执行的代码都是相同的,因此还不错。

当然,这不是我所期望的,但它对我来说效果更好。

最新更新