web-dev-qa-db-fra.com

Angular2, la vue ne se met pas à jour après des changements de variables dans la temporisation

J'essaie de configurer ma première application angular2 comme expérience et j'utilise la dernière version bêta.

Je suis confronté à un problème étrange où la variable que j'utilise à mon avis n'est pas mise à jour après avoir défini un délai d'expiration.

@Component({
    selector: "my-app",
    bindings: []
})

@View({
    templateUrl: "templates/main.component.html",
    styleUrls: ['styles/out/components/main.component.css']
})

export class MainComponent {

    public test2 = "initial text";

    constructor() {
        setTimeout(() => {
            this.test2 = "updated text"; 
        }, 500);

    }
}

Comme vous pouvez le voir, j'ai une variable nommée test2 et dans le constructeur j'ai défini un timeout de 500 ms où je mets à jour la valeur en "texte mis à jour".

Ensuite, à mon avis, main.component.html, j'utilise simplement:

{{ test2 }}

Mais la valeur ne sera jamais définie sur "texte mis à jour" et reste indéfiniment sur "texte initial" même si la partie mise à jour est touchée. Si je suis le tutoriel angular2, ils ne me donnent pas vraiment de réponse à cette solution. Je me demandais si quelqu'un aurait une idée de ce qui me manque ici.

edit: mon code complet que j'utilise, y compris le bootstrap et html etc

<html>
<head>
    <title>Angular 2</title>
    <script src="/node_modules/systemjs/dist/system.src.js"></script>
    <script src="/node_modules/reflect-metadata/reflect.js"></script>
    <script src="/node_modules/angular2/bundles/angular2.dev.js"></script>

    <script src="/node_modules/q/q.js"></script>
    <script src="/node_modules/jquery/dist/jquery.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <script src="/bower_components/breeze-client/breeze.debug.js"></script>
    <script src="/bower_components/datajs/datajs.js"></script>
    <script src="/bower_components/bootstrap-less/js/collapse.js"></script>
    <script src="/bower_components/bootstrap-less/js/modal.js"></script>

    <script src="/bower_components/signalr/jquery.signalR.js"></script>
    <script src="http://localhost:64371/signalr/js"></script>

    <link href="styles/out/main.css" type="text/css" rel="stylesheet"  />
    <script>
        System.config({
            map: {
                rxjs: '/node_modules/rxjs' // added this map section
            },
            packages: {'scripts/out': {defaultExtension: 'js'}, 'rxjs': {defaultExtension: 'js'}}
        });

        System.import('scripts/out/main');

    </script>
</head>
<body>
    <my-app>loading...</my-app>
</body>
</html>

main.ts avec le bootstrap:

import {Component} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser'
import {COMMON_DIRECTIVES} from './constants';
import {MainComponent} from './components/main.component'
bootstrap(MainComponent);

main-component.html

{{ test2 }}
21
Jurgen Welschen

Comme l'a dit Vlado, cela devrait fonctionner ;-)

Je pense que le angular2-polyfills.js la bibliothèque doit être incluse dans votre page. Je ne le vois pas. Ce fichier est essentiellement un mashup de zone.js et des métadonnées de réflexion. Les zones participent à la détection des mises à jour.

Vous pouvez regarder cette vidéo où Bryan Ford explique ce que c'est: https://www.youtube.com/watch?v=3IqtmUscE_ .

J'espère que cela vous aide, Thierry

9
Thierry Templier

Cela devrait fonctionner. Avez-vous d'autres erreurs dans la console?

@Component({
 selector: 'my-app',
 template: `<h1>Hello {{title}}</h1>`
})
export class App {
 public title: string = "World";
 constructor() {
   setTimeout(() => {
    this.title = "Brave New World"
   }, 1000);)
 }
}

Regardez ce Plunker: http://plnkr.co/edit/XaL4GoqFd9aisOYIhuXq?p=preview

6
Vlado Tesanovic

J'ai eu un problème très similaire à l'OP où même dans une configuration de base Angular2, les modifications des propriétés liées ne seraient pas reflétées automatiquement par la vue. À ce stade, nous utilisons Angular2 2.0.0-rc.6. Il n'y avait aucun message d'erreur.

En fin de compte, j'ai trouvé que le coupable était une référence à es6-promise.js, qui était "requis" par un composant tiers que nous utilisons. D'une certaine manière, cela a interféré avec la référence core-js que nous utilisons, qui est suggérée avec rc6 dans certains des tutoriels Angular2.

Dès que je me suis débarrassé de la référence es6-promise.js, la vue s'est correctement mise à jour après avoir changé une propriété sur mon composant (via Promise ou timeout).

J'espère que cela aidera quelqu'un un jour.

4
Ben

Dans Angular2 (~ 2.1.2) une autre façon de le faire fonctionner est par le biais de la classe ChangeDetectorRef. Le code de question d'origine ressemblerait à ceci:

import { 
  ChangeDetectorRef
  // ... other imports here
} from '@angular/core';

 @Component({
    selector: "my-app",
    bindings: []
})

@View({
    templateUrl: "templates/main.component.html",
    styleUrls: ['styles/out/components/main.component.css']
})

export class MainComponent {

    public test2 = "initial text";

    constructor(private cd: ChangeDetectorRef) {
        setTimeout(() => {
            this.test2 = "updated text"; 

            // as stated by the angular team: the following is required, otherwise the view will not be updated
            this.cd.markForCheck();

        }, 500);
    }
}
3
artemisian