gpt4 book ai didi

javascript - AngularJs - UI 中的字段未反射(reflect)更新的模型值

转载 作者:搜寻专家 更新时间:2023-11-01 05:22:54 25 4
gpt4 key购买 nike

Here's the Plunkr

一个常见的场景,我有一个 ng-repeat 中显示的项目集合。对于显示的每一行,我都有一个启动过程(文件上传)的按钮和一个状态字段。我希望我的 UI 能够在流程状态发生变化时反射(reflect)出来。这在带有双向绑定(bind)的 Angular 中应该很容易,对吧?

我在 ng-repeat 上创建了第二个(子) Controller ,这样我就可以简单地更新它自己范围内的项目状态,而不是处理项目集合,特别是因为这个过程是异步的,用户会可能同时上传许多文件。

问题:我对 Ang/JS 中的 $scope 缺乏理解 - 哈哈。但严重的是,当作用域模型值更新时,UI 中的绑定(bind) {{xxx}} 值不会更新。单击任一按钮并查看警报。如何让 UI 正确更新?

仅供引用 - 实际上,该按钮调用外部库上的 API 来上传文件并返回给我一个 url 以检查我的上传状态。然后我在 setInterval() 循环中轮询 url 以 ping 状态直到完成或错误。我在 Plunkr 中简化了该部分,因为这种复杂性本身并不是问题所在。 Plunkr

    <!DOCTYPE html>
<html ng-app="myapp">

<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.2.x" src="http://code.angularjs.org/1.2.7/angular.js" data-semver="1.2.7"></script>
<script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
<table>
<th></th>
<th>Id</th>
<th>Name</th>
<th>Status</th>
<tr ng-repeat="item in items" ng-controller="ChildCtrl">
<td><button ng-click="updateStatus(item)">click</button></td>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.status}}</td>
</tr>

</table>
</body>

</html>

JS

var app = angular.module('myapp', []);

app.controller('MainCtrl', function($scope) {
$scope.items = [ {id: 1, name: "Moe", status: "init"}
, {id: 3, name: "Larry", status: "init"}
, {id: 2, name: "Curly", status: "init"}
];
});


app.controller('ChildCtrl', function($scope) {
$scope.updateStatus = function(item){
$scope.myItem = item;
alert('child: ' + item.id + ' status: ' + item.status);
item.status = 'clicked';
alert('status just update in UI to: ' + item.status);

callResult = fakeAjaxCall($scope);
alert('callResult: ' + callResult);
};

var fakeAjaxCall = function(scope){
setTimeout(function (item) {
if (-1 == -1) { //success
result = "Wow, it worked!";
alert('current status: ' + scope.myItem.status);
alert('ajax result: ' + result);
scope.myItem.status = result;
alert('new status: ' + scope.myItem.status);
alert("but the status in the UI didn't update");
}
}, 2000);
};

});

最佳答案

您需要使用 $timeout而不是 setTimeout 从更新模式的 Angular 内调用摘要循环,或者您必须自己调用摘要循环(通过包装代码 scope.$apply()scope.evalAsync etc...) ,原因是 Angular 不知道 setTimeout 何时完成,因为它不会在 Angular 内发生。当你 Angular 方式做事并且你可以自由使用它时,你应该尽量不要手动调用摘要循环。在这种情况下,您可以将 setTimeout 替换为 $timeout 并且模型更改将自动反射(reflect)在 View 中,因为当 $timeout 完成了。还有一个优点是,当使用 $timeout 时,它也会返回一个 promise,您可以将其链接起来,并且在与 setTimeout 相对时仍然实现了 promise 模式。

app.controller('ChildCtrl', function($scope, $timeout) {
$scope.updateStatus = function(item){
$scope.myItem = item;
console.log('child: ' + item.id + ' status: ' + item.status);
item.status = 'clicked';
console.log('status now updates in UI to: ' + item.status);

callResult = fakeAjaxCall($scope);
console.log('callResult: ' + callResult);
};

var fakeAjaxCall = function(scope){
$timeout(function (item) {
if (-1 == -1) { //success
result = "Wow, it worked!";
console.log('current status: ' + scope.myItem.status);
console.log('ajax result: ' + result);
scope.myItem.status = result;
console.log('new status: ' + scope.myItem.status);
console.log("but the status in the UI doesn't update");
}
}, 2000);
};

Plnkr

在调试异步操作时,我建议使用 console.log(或 $log)而不是 alert 进行调试。

关于javascript - AngularJs - UI 中的字段未反射(reflect)更新的模型值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25233932/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com