一般的なシナリオとして、ng-repeat に表示されるアイテムのコレクションがあります。表示される行ごとに、プロセス (ファイルのアップロード) を開始するボタンとステータス フィールドがあります。プロセスのステータスが変わるたびに、UI に反映させたいと思います。これは、Angular の 2 ウェイ バインディングで簡単にできるはずですよね?
特にこのプロセスは非同期であり、ユーザーは多くのアイテムをアップロードする可能性があるため、アイテムのコレクションを処理するのではなく、独自のスコープでアイテムのステータスを簡単に更新できるように、ng-repeat に 2 番目の (子) コントローラーを作成しました。ファイルを同時に。
問題: Ang/JS の $scope の理解が不足しています - 笑。真剣に、UI のバインドされた {{xxx}} 値は、スコープ モデルの値が更新されても更新されません。いずれかのボタンをクリックして、アラートを監視します。UI を正しく更新するにはどうすればよいですか?
参考までに - 実際には、そのボタンは外部ライブラリの API を呼び出してファイルをアップロードし、アップロードのステータスを確認するための URL を返します。次に、setInterval() ループで URL をポーリングして、完了またはエラーになるまでステータスを ping します。この複雑さ自体は問題ではないため、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);
};
});