controllerAs 構文を使用していますが、何らかの理由で、コントローラーのフィールドを $interval で更新すると、ビュー内の要素が適切に表示/非表示になりません。angularのUIルーターを使用しています。
この問題は、私が考えるコードで最もよく説明されているので、コード ダンプを許してください。
私の状態(「refreshLogs」は、単に更新されたログのために logService を呼び出す関数です):
angular.module('portal')
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('logs', {
'abstract': true,
views: {
"@": { template: '<div ui-view></div>' }
}
})
.state('logs.view', {
url: '/logs/:id',
resolve: {
log: function ($stateParams, logService) {
return logService.getLog($stateParams.id);
},
refreshLog: function ($stateParams, logService) {
var id = $stateParams.id
var fn = function (id) {
return logService.getLog(id)
};
return function() { return fn(id) }
}
},
templateUrl: '/app/logs/viewlog.html',
controller: 'logController',
controllerAs: 'vm'
})
});
私のコントローラー:
angular.module('portal.controllers')
.controller('logController', function ($state, log, refreshLog, $scope, $interval) {
var vm = this;
vm.log = log;
vm.refreshTimer = $interval(function () {
refreshLog().then(function (data) {
vm.log = data;
})
}, 15000);
$scope.$on("$destroy", function () {
if (angular.isDefined(vm.refreshTimer)) {
$interval.cancel(vm.refreshTimer);
}
});
});
そして最後にビュー:
<div ng-show="{{ vm.log != null }}">
<div class="page-header">
<h1>{{ vm.log.JobType }} ({{ vm.log.JobResult }})</h1>
</div>
Parameters: {{ vm.log.JobParameters }}
<pre>{{ vm.log.Content }}</pre>
</div>
<div ng-show="{{ vm.log == null }}">
<div class="page-header">
<h1>Waiting for log...</h1>
</div>
</div>
DOM 更新で「ng-show」値が表示されますが、この値に基づいて要素が表示/非表示になりません。Chrome で DOM を調べたところ、次のように表示されました (強調のためにアスタリスクが追加されています)。
<div ui-view="" class="ng-scope"><div ng-show="**false**" class="ng-binding ng-scope ng-hide">
<div class="page-header">
<h1 class="ng-binding"> ()</h1>
</div>
Parameters:
<pre class="ng-binding"></pre>
</div>
<div ng-show="**true**" class="ng-scope">
<div class="page-header">
<h1>Waiting for log...</h1>
</div>
</div></div>
どちらが正しいか、適切な div が表示されます。数秒後、ログが更新され、"vm.log" 変数が null 以外の値に設定されます (この値を割り当てる JS コードにブレークポイントを設定したため、これは正しいように見えます)。その後、DOM を再度検査すると、次のように表示されます。
<div ui-view="" class="ng-scope"><div ng-show="**true**" class="ng-binding ng-scope ng-hide">
<div class="page-header">
<h1 class="ng-binding">...</h1>
</div>
...
</pre>
</div>
<div ng-show="**false**" class="ng-scope">
<div class="page-header">
<h1>Waiting for log...</h1>
</div>
</div></div>
正しい値を示す「ng-show」属性に注意してください。だから、表現は明らかに再評価されました。ただし、古い「Waiting for log...」ヘッダーは引き続き表示され、最初の div は表示されません (「ng-hide」CSS クラスが適用されたままです)。
ここで何が欠けていますか?