在Angular中更改模型后如何更新视图?

Posted

技术标签:

【中文标题】在Angular中更改模型后如何更新视图?【英文标题】:How to update the view after changing the model in Angular? 【发布时间】:2015-06-04 20:08:02 【问题描述】:

如何让 Angular 传播我对模型所做的更改。在 AngularJS 中,这真的很容易,但我似乎无法让它在 Angular 中工作。我知道整个变化检测系统和视图传播完全改变了。不知何故,我需要通知角度的变化。但是我如何在实践中做到这一点。

查看这段打字稿代码:

import Component, View, bootstrap, For from 'angular2/angular2';

// Annotation section
@Component(
    selector: 'app'
)
@View(
    template: `
    <div *for="#user of users">
        user
    </div>
    `,
    directives: [For]
)
class App 
    users:Array<String>;

    constructor() 
        this.users = [];
        this.fillUsersAsync();
    

    fillUsersAsync()
        window['fetch']('http://jsonplaceholder.typicode.com/users')
            .then( resp => resp.json())
            .then( users => users.forEach(user => this.users.push(user.name)))
            .then( () => console.log('Retrieved users and put on the model: ', this.users));
    


bootstrap(App);

您会看到,在用户加载到模型后,视图不会更新。

我正在使用 systemjs 0.16,角度 2.0.0-alpha.23。

See this plnkr for the example(目前仅适用于 chrome,因为使用了新的 'fetch' api)

【问题讨论】:

【参考方案1】:

我发现了问题。显然,这是一个在 alpha 27 中修复的错误。请参阅此错误报告:https://github.com/angular/angular/issues/1913

Angular2 使用 zonejs 知道何时开始摘要循环(脏检查和更新视图)。到目前为止,zonejs在使用new window.fetch()获取数据后没有被触发。

将 window['fetch'] 行替换为此解决了我的问题: Zone.bindPromiseFn(window['fetch'])('http://jsonplaceholder.typicode.com/users')

【讨论】:

【参考方案2】:

要在 AngularJS2 中更新视图中的数据,您应该使用 Forms。您可以在page 阅读有关此内容的信息或查看更多详细信息here。 如果我正确理解表单,您应该像这样修改 @View 部分:

@View(
    template: `
    <div *for="#user of users" control="users">
        user
    </div>
    `,
    directives: [For]
)

--已编辑

试试这个:

import Component, View, bootstrap, For from 'angular2/angular2';

// Annotation section
@Component(
    selector: 'app'
)
@View(
    template: `
    <div [control]="users" *for="#user of users">
        user.value
    </div>
    `,
    directives: [For, forms]
)
class App 
    users:Array<String>;

    constructor() 
        this.users = new Control([]);
        this.fillUsersAsync();
    

    fillUsersAsync()
        window['fetch']('http://jsonplaceholder.typicode.com/users')
            .then( resp => resp.json())
            .then( users => 
                var usersArr = []
                users.forEach(user => 
                      usersArr.push(user.name))
                this.users = new Control(usersArr));
        
 

 bootstrap(App);

我不确定我的回答是否完全正确,但我找不到更多信息。试用此代码,愿原力与您同在! :)

我还发现this link,非常信息丰富。

据我了解,在构造函数中,您应该通过 new Control(some data) 初始化 users 变量,然后在视图模板中,您可以像这样访问这些数据 - users.value

如果它不起作用:尝试相同但非常简单的数据,例如使用字符串而不是数组。

this video 将有助于理解 ng2 中的表单。

【讨论】:

您的第二个链接似乎让我走上了正确的道路,但该文件似乎已过时。我想我需要指令数组中的某种形式指令,但是名称是什么,以及如何导入它? @nicojs 建议按照第一个链接的示例进行操作,如果它不起作用,请按照第二个链接的示例进行操作。 forms 的指令名称 - 指令:[forms] 或者可能是 [Forms]。像导入 [For] 指令一样导入它。试试这个并报告,我会尽力帮助你。 我都试过了,但还是不行。我认为我们正在寻找错误的方向。据我所知,angular2 仍然使用脏检查来查看模型是否更改。不知何故,我需要通知 angular2 我更新了模型。或者使用 $http 等价物。 我认为我们遗漏了一些东西......它必须与 [control] 语句一起使用。我在几分钟内编辑我的答案。请检查一下。【参考方案3】:

刚刚在这里回复Angular2 View Not Changing After Data Is Updated

基本上,Beta 2.0.0-beta.1 中有一个错误。

希望对你有帮助!

【讨论】:

【参考方案4】:

Ng 前缀又回来了。 For 现在已变为 ngFor 用于 Angular2 版本 alpha-24+。

import NgFor from 'angular2/directives';
@View(
  directives: [ngFor]
)

然后在模板中使用*ng-for=#user of users"

查看ngFor docs 或a working example

【讨论】:

问题不在于,它工作正常。这就是为什么我指定我使用的是 alpha-22。但是在 angular2 评估视图时,用户数组仍然是空的。问题是在获取完成后 angular2 没有被告知模型中的更改。据我所知,angular2 没有使用 Object.observe,但仍然使用脏检查来检查更改。所以它不知道视图的变化。在 Angular 1.x 中,您将使用 $http,甚至 $apply。是否有 angular2 等价物? 对于 alpha 代码,您可能需要考虑坚持使用最新版本以避免更多错误和不完整的功能。在 Angular2 中没有 $apply,也没有必要,视图应该只根据模型更新。你可以在 ng2 中使用任何请求方法来代替 $http。请参阅来自 Angular 的创建者的 this response。 好的,不需要 $apply。但是必须有某种方法来通知我的更改的更改检测。它不会轮询它,也不会使用 Object.observe。那么我该如何解决呢? 其实有:_ngZone.run()。见angular.io/docs/js/latest/api/core/NgZone-class.html

以上是关于在Angular中更改模型后如何更新视图?的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2组件模型刷新视图,无需模型更改

Angular 8 值在更改后不会在视图上更新

在Angular2中更改组件变量后视图未更新

Angular 2 - 在 Promise 中更改模型时 GUI 不会更新

Django:渲染视图后如何更新模型?

当模型被事件更改时如何渲染 Angular 视图?