在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中更改模型后如何更新视图?的主要内容,如果未能解决你的问题,请参考以下文章