Electron + Angular 4 = 两种方式的数据绑定不起作用

Electron + Angular 4 = two ways data binding not working

每次我们想要更新 UI 时,我们都被迫使用 zone.run() 方法,这不是一种选择,因为它不直观并迫使开发人员添加更多重复代码。

这里是我们的主要依赖:

  "dependencies": {
"@angular/animations": "4.0.0",
"@angular/common": "4.0.0",
"@angular/compiler": "4.0.0",
"@angular/compiler-cli": "4.0.0",
"@angular/core": "4.0.0",
"@angular/forms": "4.0.0",
"@angular/http": "4.0.0",
"@angular/platform-browser": "4.0.0",
"@angular/platform-browser-dynamic": "4.0.0",
"@angular/platform-server": "4.0.0",
"@angular/router": "4.0.0",
"@angular/upgrade": "4.0.0",
"@types/electron": "^1.4.34",

这里是我们 index.html 的片段:

    <!-- 1. Load libraries -->
<script src="../node_modules/zone.js/dist/zone.js"></script>
<script src="../node_modules/reflect-metadata/Reflect.js"></script>
<script src="../node_modules/systemjs/dist/system.src.js"></script>

<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
  System.import('app').catch(function(err){ console.error(err); });
</script>

这里是systemjs.config.js相关部分

(function (global) {
System.config({
    paths: {
        // paths serve as alias
        'npm:': '../node_modules/'
    },
    // map tells the System loader where to look for things
    map: {
        // our app is within the app folder
        app: 'app',

        // angular bundles
        '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
        '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
        '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
        '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
        '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
        '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
        '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
        '@angular/router/upgrade': 'npm:@angular/router/bundles/router-upgrade.umd.js',
        '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
        '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
        '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',

        // other libraries
        'ng2-translate': 'npm:ng2-translate/bundles',
        'rxjs': 'npm:rxjs',
        'underscore.string': 'npm:underscore.string/dist',
        'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
    },

现在 Chrome 开发控制台内没有错误报告,但有些问题无法正常工作:

其他相关来源是组件和 html

组件及其模板(当我们在字段中键入时,我们期望 form.value | json显示'live'输入文本的内容)

import { Component, OnInit, NgZone } from '@angular/core';
import { Router } from '@angular/router';

import { AuthenticationService, ILoginAjaxResponse } from './service/authentication.service';

export class Credentials {
    email: string;
    password: string;
}

@Component({
    selector: 'as-login',
    templateUrl: 'app/login/login.component.html',
})
export class LoginComponent implements OnInit {
    credentials = new Credentials();

    constructor(
        private authenticationService: AuthenticationService,
        private router: Router,
        private zone: NgZone) {
    }

    public ngOnInit() {
        // Test A
        // -------------------------------
        // this is visible in UI text box
        // this is visible in the UI {{credentials | json}} output
        // this is NOT visible in the UI {{form.value | json}} output
        this.credentials.email = 'john.doe@planet.com';

        // Test B
        // -------------------------------
        // this is NOT visible in UI text box
        // this is NOT visible in the UI {{credentials | json}} output
        // this is NOT visible in the UI {{form.value | json}} output
        setTimeout(() => {
            this.credentials.email = '11111111@planet.com'
        }, 3000);

        // Test C
        // -------------------------------
        // this is visible in UI text box
        // this is visible in the UI {{credentials | json}} output
        // this is visible in the UI {{form.value | json}} output
        setTimeout(() => {
            this.zone.run(() => {
                this.credentials.email = '22222222@planet.com'
            });
        }, 6000);
    }

    public onSubmit() {
        this.authenticationService.login(this.credentials)
            .subscribe((response) => this.handleResponse(response));
    }

    private handleResponse(response: ILoginAjaxResponse) {
        this.router.navigateByUrl('spa/sync')
            .catch((reason) => { console.log(reason); });
    }

}
<p>Form:</p>
<pre>
{{ form.value | json }}
</pre>

<p>Model:</p>
<pre>
{{ credentials | json }}
</pre>

<form #form="ngForm" novalidate>
    <input type="text" class="form-control"
        name="email" [(ngModel)]="credentials.email">

    <input type="password" class="form-control"
        name="password"  [(ngModel)]="credentials.password">

    <input class="btn btn-lg btn-primary btn-block"
        (click)="onSubmit()"
        type="submit" value="Submit">
</form>

终于找到了解决办法。这与我最初怀疑的 index.html 内的订单或进口或标签无关。 这与This issue causing angular to drop out the zone有关。所以解决方案是像问题解决方法中提到的那样使用 Zone.current.wrap...