我是Angular(1.x)的初学者,我一直试图将其拼接到我目前正在开发的应用中。
它基本上通过ajax(多个嵌套数组)接收整个用户数据,然后使用嵌套的ng-repeat指令继续渲染它们。在最里面的重复中,我运行一个函数,该函数根据当前日期返回数据。
<div ng-repeat="i in rootArray">
<div ng-repeat="h in i.array1">
<div ng-repeat="j in h.array2">
<span>{{dateBasedFunction(j.data)}}</span>
</div>
</div>
</div>
&#13;
函数中的数据会随着时间的推移而变化(即使输入保持不变),我希望它能够重新运行以反映这些变化,而无需再次渲染整个结构。
有可能吗?我不确定我是否遵循最佳框架的做法,也许有更好的方法?
谢谢!
答案 0 :(得分:0)
<强>背景强>
ng-repeats在这里没有引起任何问题。我们需要关注interpolation expression:{{dateBasedFunction(j.data)}}
Angular正在watcher创建一个digest来检查angular-moment周期的每次迭代中的表达式dateBasedFunction(j.data)
。如果自上次摘要以来结果值已更改,则将使用新值更新DOM。
问题是,代码中没有任何内容触发Angular摘要周期。
工作示例
在这里,我们可以通过用户交互手动触发摘要来查看您的情况:
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', ['$scope', MyCtrl]);
function MyCtrl($scope) {
$scope.rootArray = [{
"array1": [{
"array2": [{
"data": "hello"
}, {
"data": "world"
}]
}]
}];
//Dummy $watch alerts whenever digest is called
$scope.$watch(function() {
console.log('Digest called');
});
$scope.dateBasedFunction = function(x) {
var d = new Date();
return x + ' (' + d.getMinutes() + ":" + d.getSeconds() + ")";
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<button ng-click="">ng-click calls digest()</button>
<div ng-repeat="i in rootArray">
<div ng-repeat="h in i.array1">
<div ng-repeat="j in h.array2">
<span>{{dateBasedFunction(j.data)}}</span>
</div>
</div>
</div>
</div>
</div>
每次单击该按钮,ng-click
都会触发Angular摘要。这会重新评估dateBasedFunction
。由于值已更改,因此DOM将重新绘制。
但是,我假设您不想依赖ng-click
来更新DOM。您希望DOM定期更新,因为它会根据当前日期/时间而更改。
可能的解决方案
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', ['$scope', MyCtrl]);
function MyCtrl($scope) {
$scope.rootArray = [{
"array1": [{
"array2": [{
"data": "hello"
}, {
"data": "world"
}]
}]
}];
//Dummy $watch alerts whenever digest is called
$scope.$watch(function() {
console.log('Digest called');
});
$scope.dateBasedFunction = function(x) {
var d = new Date();
return x + ' (' + d.getMinutes() + ":" + d.getSeconds() + ")";
}
//Call $scope.$apply() every second.
setInterval(function() {
//$scope.$apply() triggers a digest cycle
$scope.$apply();
}, 1000);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<div ng-repeat="i in rootArray">
<div ng-repeat="h in i.array1">
<div ng-repeat="j in h.array2">
<span>{{dateBasedFunction(j.data)}}</span>
</div>
</div>
</div>
</div>
</div>
如果您知道更新的频率,您可以考虑编写一个在适当的时间直接更新DOM的指令,而不需要在整个范围内调用apply()
。这将更有效,但需要更多的开发工作。
这正是am-time-ago
directive对This article所做的事情。该指令具有类似的目标:更新响应当前日期/时间而变化的数据。
使用Angular观察模型是否有任何变化,但在Angular之外处理基于日期/时间的更改:
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', ['$scope', MyCtrl]);
function MyCtrl($scope) {
$scope.rootArray = [{
"array1": [{
"array2": [{
"data": "hello"
}, {
"data": "world"
}]
}]
}];
//Dummy $watch alerts whenever digest is called
$scope.$watch(function() {
console.log('Digest called');
});
}
function dateBasedFunction(x) {
var d = new Date();
return x + ' (' + d.getMinutes() + ":" + d.getSeconds() + ")";
}
setInterval(function() {
$('[data-date-based-value]').each(function() {
this.textContent = dateBasedFunction(this.dataset['dateBasedValue']);
});
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<div ng-repeat="i in rootArray">
<div ng-repeat="h in i.array1">
<div ng-repeat="j in h.array2">
<!--Set a data-date-based-value attribute-->
<!--Angular will keep the attribute value updated-->
<!--But the element's text will be updated via jQuery-->
<span ng-attr-data-date-based-value="{{j.data}}"></span>
</div>
</div>
</div>
</div>
</div>
请注意,此解决方案直接更新DOM,而不运行其他摘要周期。
如果您有兴趣了解有关Angular的更多信息,this可以很好地解释摘要周期。