ng-if 被调用的次数超过它应该的次数
ng-if being called more times than it should
我正在尝试根据所选类别过滤一些频道。
我有一个 channel in channels
的 ng-repeat,它有一个 ng-if="hasCategory(channel.category)
这是文档:
db.channels.find().pretty()
{
"_id" : "2kj9GK8jE9yHezoWb",
"name" : "example name",
"logo" : "path/to/image.svg",
"number" : 2,
"category" : [
"Broadcast",
"Premium"
],
"tags" : "example tag tags"
}
这是处理 ng-if 的函数:
$scope.hasCategory = function (categoryNameArray) {
console.log('thisisbeingcalled');
var e = _.indexOf(categoryNameArray, $scope.activeCategory);
if (e === -1) {
return false;
} else {
return true;
}
};
这就是我设置活动类别的方式:
$scope.setCategory = function (name) {
$scope.activeCategory = name;
};
我通过单击视图中的按钮发送:
<section layout="row" layout-align="center center" layout-wrap ng-init="activeIndex; activeCategory">
<md-button flex="auto" flex-sm="45" flex-xs="100" ng-repeat="kit in kits | orderBy: 'order'" ng-class="{active: (activeIndex.index == $index)}" class="md-raised">
<a href="" ng-click="activeIndex.index = $index; setCategory(kit.name);" class="bold">{{kit.name}}</a>
</md-button>
</section>
这是套件文档架构:
db.kits.find().pretty()
{ "_id" : "k7JFX6DHu5GYnyer3", "name" : "Broadcast", "order" : 1 }
{ "_id" : "KrKRm4gysw5sfQnnr", "name" : "Premium", "order" : 2 }
{ "_id" : "dieukQ3NRsA44CSns", "name" : "Ultimate", "order" : 3 }
现在我只有一个渠道来测试这个,但每次我点击按钮更改类别时,即使在页面启动时 $scope.hasCategory
函数也会被多次调用(第一次加载)
我还有一个搜索栏可以搜索当前类别中的频道,我不确定这是否也会影响这一点。
<input type="text" ng-model="queryname" ng-model-options="{debounce: 500}">
现在,当我有超过 100 个频道时,这变得非常缓慢,ng-if 被调用超过 10k 次,这使得页面冻结了很长一段时间。
我该怎么做才能解决这个问题?
编辑
忘记添加 ng-if
的位置:
<md-card flex="15" flex-xs="40" class="slide-up" layout="column" ng-repeat="channel in channels | orderBy: 'number' | filter: queryname" ng-if="hasCategory(channel.category)" ng-init="channel.edit = false">
<md-card-header ng-show="channel.edit == false">
<img ng-src="{{channel.logo}}" alt="">
</md-card-header>
<md-card-header-text ng-show="channel.edit == false">
<span class="md-subhead dark-blue" layout="row" layout-align="center" layout-margin>{{channel.number}}</span>
</md-card-header-text>
</md-card>
您的 ng-if
将在每个摘要循环中调用。问题是它包含一个涉及函数调用的表达式。 Angular 无法知道表达式的结果何时会发生变化,因此每次都会调用它。
更好的选择是在每个通道中设置一个标志并使用 ng-if 来测试相关标志。然后,您只需在 $scope.activeCategory
更改时更新标志,您可以使用设置类别的代码或使用 $scope.$watch()
自动触发它。
例如
$scope.setCategory = function (name) {
$scope.activeCategory = name;
for (var index=0; index < $scope.channels.length; index++) {
$scope.channels[index].hasCategory = hasCategory($scope.channels[index].category, name);
}
};
function hasCategory(categoryNameArray, name) {
console.log('thisisbeingcalled');
var e = _.indexOf(categoryNameArray, name);
if (e === -1) {
return false;
} else {
return true;
}
}
然后在您的模板中:
<md-card flex="15" flex-xs="40" class="slide-up" layout="column"
ng-repeat="channel in channels | orderBy: 'number' | filter: queryname"
ng-if="channel.hasCategory"
ng-init="channel.edit = false">
<md-card-header ng-show="channel.edit == false">
<img ng-src="{{channel.logo}}" alt="">
</md-card-header>
<md-card-header-text ng-show="channel.edit == false">
<span class="md-subhead dark-blue" layout="row" layout-align="center" layout-margin>{{channel.number}}</span>
</md-card-header-text>
</md-card>
应该更有效率。
我正在尝试根据所选类别过滤一些频道。
我有一个 channel in channels
的 ng-repeat,它有一个 ng-if="hasCategory(channel.category)
这是文档:
db.channels.find().pretty()
{
"_id" : "2kj9GK8jE9yHezoWb",
"name" : "example name",
"logo" : "path/to/image.svg",
"number" : 2,
"category" : [
"Broadcast",
"Premium"
],
"tags" : "example tag tags"
}
这是处理 ng-if 的函数:
$scope.hasCategory = function (categoryNameArray) {
console.log('thisisbeingcalled');
var e = _.indexOf(categoryNameArray, $scope.activeCategory);
if (e === -1) {
return false;
} else {
return true;
}
};
这就是我设置活动类别的方式:
$scope.setCategory = function (name) {
$scope.activeCategory = name;
};
我通过单击视图中的按钮发送:
<section layout="row" layout-align="center center" layout-wrap ng-init="activeIndex; activeCategory">
<md-button flex="auto" flex-sm="45" flex-xs="100" ng-repeat="kit in kits | orderBy: 'order'" ng-class="{active: (activeIndex.index == $index)}" class="md-raised">
<a href="" ng-click="activeIndex.index = $index; setCategory(kit.name);" class="bold">{{kit.name}}</a>
</md-button>
</section>
这是套件文档架构:
db.kits.find().pretty()
{ "_id" : "k7JFX6DHu5GYnyer3", "name" : "Broadcast", "order" : 1 }
{ "_id" : "KrKRm4gysw5sfQnnr", "name" : "Premium", "order" : 2 }
{ "_id" : "dieukQ3NRsA44CSns", "name" : "Ultimate", "order" : 3 }
现在我只有一个渠道来测试这个,但每次我点击按钮更改类别时,即使在页面启动时 $scope.hasCategory
函数也会被多次调用(第一次加载)
我还有一个搜索栏可以搜索当前类别中的频道,我不确定这是否也会影响这一点。
<input type="text" ng-model="queryname" ng-model-options="{debounce: 500}">
现在,当我有超过 100 个频道时,这变得非常缓慢,ng-if 被调用超过 10k 次,这使得页面冻结了很长一段时间。
我该怎么做才能解决这个问题?
编辑
忘记添加 ng-if
的位置:
<md-card flex="15" flex-xs="40" class="slide-up" layout="column" ng-repeat="channel in channels | orderBy: 'number' | filter: queryname" ng-if="hasCategory(channel.category)" ng-init="channel.edit = false">
<md-card-header ng-show="channel.edit == false">
<img ng-src="{{channel.logo}}" alt="">
</md-card-header>
<md-card-header-text ng-show="channel.edit == false">
<span class="md-subhead dark-blue" layout="row" layout-align="center" layout-margin>{{channel.number}}</span>
</md-card-header-text>
</md-card>
您的 ng-if
将在每个摘要循环中调用。问题是它包含一个涉及函数调用的表达式。 Angular 无法知道表达式的结果何时会发生变化,因此每次都会调用它。
更好的选择是在每个通道中设置一个标志并使用 ng-if 来测试相关标志。然后,您只需在 $scope.activeCategory
更改时更新标志,您可以使用设置类别的代码或使用 $scope.$watch()
自动触发它。
例如
$scope.setCategory = function (name) {
$scope.activeCategory = name;
for (var index=0; index < $scope.channels.length; index++) {
$scope.channels[index].hasCategory = hasCategory($scope.channels[index].category, name);
}
};
function hasCategory(categoryNameArray, name) {
console.log('thisisbeingcalled');
var e = _.indexOf(categoryNameArray, name);
if (e === -1) {
return false;
} else {
return true;
}
}
然后在您的模板中:
<md-card flex="15" flex-xs="40" class="slide-up" layout="column"
ng-repeat="channel in channels | orderBy: 'number' | filter: queryname"
ng-if="channel.hasCategory"
ng-init="channel.edit = false">
<md-card-header ng-show="channel.edit == false">
<img ng-src="{{channel.logo}}" alt="">
</md-card-header>
<md-card-header-text ng-show="channel.edit == false">
<span class="md-subhead dark-blue" layout="row" layout-align="center" layout-margin>{{channel.number}}</span>
</md-card-header-text>
</md-card>
应该更有效率。