Angular 带有 ng-repeat 的 1.5 过滤器不能按 id 按轨道工作
Angular 1.5 filter with ng-repeat not working by track by id
所以我尝试了很多不同的方法来完成这项工作。关注了这么多 Whosebug 却无法让它发挥作用。我要做的就是根据布尔值 属性 过滤一些列表项。下面是我的对象数据的图片。我关注的最接近的例子是这个问题 Filtering an Angular 1.2 ng-repeat with "track by" by a boolean property。还是行不通。它与对象文字有什么关系吗?这种使用 属性 的过滤仅适用于数组?我是 javascript 的新手,所以不确定。同样使用 angular material、虚拟重复容器和其他基于 material 的东西不会影响结果,我可以显示整个数据,只是通过这个特定的 属性 过滤不起作用
loadAssets = () => {
var self = this;
self.infiniteAssets = {
numLoaded_: 0,
toLoad_: 0,
items: [],
pageNum:1,
virtualIndex:0,
getItemAtIndex: function (index) {
this.virtualIndex=index;
if (index > this.numLoaded_) {
this.fetchMoreItems_(index);
return null;
}
return this.items[index];
},
// Required.
getLength: function () {
if (this.virtualIndex > this.numLoaded_) {
return this.numLoaded_ ;
}else{
return this.numLoaded_ + 5 ;
}
},
fetchMoreItems_ : function (index) {
if (this.toLoad_ < index) {
self.loading = true;
this.toLoad_ += 20;
self.siAsset.getAssets(this.pageNum++,20)
.then(angular.bind(this, function (assets) {
//this.objLength = assets.length;
if(! assets.statusCode){
this.items = this.items.concat(assets);
this.toLoad_ = this.items.length;
this.numLoaded_ = this.toLoad_;
}
self.loading = false;
}))
}
}
};
console.log('++++++++++',self.infiniteAssets)
<md-virtual-repeat-container id="vertical-container" ng-show="$ctrl.infiniteAssets.getLength() > 0 && $ctrl.switch">
<md-list>
<md-list-item class="list-page" md-on-demand md-virtual-repeat="asset in $ctrl.infiniteAssets | filter: {disabled: true } track by asset.id" ng-click="$ctrl.loadDetail(asset)">
<span class="search-status" style="border-left-color:{{asset.statusColor}};"></span>
<p >{{asset.name}} </p>
<label hide-xs ng-if="asset.disabled" class="ng-animate-disabled">
<md-chips >
<md-chip >{{'LABELS.DISABLED' | translate}}</md-chip>
</md-chips>
</label>
<label ><i>{{asset.status || 'UNKNOWN'}}</i></label>
<md-button aria-label="Delete Asset" class="md-icon-button md-warn" layout-padding ng-click="$ctrl.deleteAsset(asset)">
<md-icon md-svg-icon="delete" class="modelTrashIcon"></md-icon>
</md-button>
<md-divider></md-divider>
</md-list-item>
</md-list>
</md-virtual-repeat-container>
正如你所说,"Angular 1.5 filter with ng-repeat not working by track by id"
我使用 AngularJs 1.5
创建了示例示例,并在 ng-repeat
上使用了带跟踪依据的过滤器。
angular.module('controllerAsExample', [])
.controller('SettingsController1', SettingsController1);
function SettingsController1() {
this.infiniteAssets = [
{disabled :false, name:'test0',id:234 },
{disabled :true, name:'test1',id:123 },
{disabled :false, name:'test2',id:345 }
];
//console.log(this.infiniteAssets);
}
<!doctype html>
<html >
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
</head>
<body ng-app="controllerAsExample">
<div ng-controller="SettingsController1 as settings">
<p>ng-repeat with track by field example using angularjs 1.5.0:</p>
<ul>
<li ng-repeat="asset in settings.infiniteAssets | filter: {disabled: false } track by asset.id">
{{asset.name}}
</li>
</ul>
</div>
</body>
</html>
您确定 md-virtual-repeat
可以使用过滤器吗? AngularJS Materials virtual repeat 是 ng-repeat 的自定义实现,因此您不能指望它能像原来一样工作。这是文档中的内容。
Virtual repeat is a limited substitute for ng-repeat that renders only
enough DOM nodes to fill the container and recycling them as the user
scrolls.
Arrays, but not objects are supported for iteration. Track by, as
alias, and (key, value) syntax are not supported.
我会改为将过滤器移到您的控制器中,并确保在集合发生变化时重新应用过滤器。
所以我尝试了很多不同的方法来完成这项工作。关注了这么多 Whosebug 却无法让它发挥作用。我要做的就是根据布尔值 属性 过滤一些列表项。下面是我的对象数据的图片。我关注的最接近的例子是这个问题 Filtering an Angular 1.2 ng-repeat with "track by" by a boolean property。还是行不通。它与对象文字有什么关系吗?这种使用 属性 的过滤仅适用于数组?我是 javascript 的新手,所以不确定。同样使用 angular material、虚拟重复容器和其他基于 material 的东西不会影响结果,我可以显示整个数据,只是通过这个特定的 属性 过滤不起作用
loadAssets = () => {
var self = this;
self.infiniteAssets = {
numLoaded_: 0,
toLoad_: 0,
items: [],
pageNum:1,
virtualIndex:0,
getItemAtIndex: function (index) {
this.virtualIndex=index;
if (index > this.numLoaded_) {
this.fetchMoreItems_(index);
return null;
}
return this.items[index];
},
// Required.
getLength: function () {
if (this.virtualIndex > this.numLoaded_) {
return this.numLoaded_ ;
}else{
return this.numLoaded_ + 5 ;
}
},
fetchMoreItems_ : function (index) {
if (this.toLoad_ < index) {
self.loading = true;
this.toLoad_ += 20;
self.siAsset.getAssets(this.pageNum++,20)
.then(angular.bind(this, function (assets) {
//this.objLength = assets.length;
if(! assets.statusCode){
this.items = this.items.concat(assets);
this.toLoad_ = this.items.length;
this.numLoaded_ = this.toLoad_;
}
self.loading = false;
}))
}
}
};
console.log('++++++++++',self.infiniteAssets)
<md-virtual-repeat-container id="vertical-container" ng-show="$ctrl.infiniteAssets.getLength() > 0 && $ctrl.switch">
<md-list>
<md-list-item class="list-page" md-on-demand md-virtual-repeat="asset in $ctrl.infiniteAssets | filter: {disabled: true } track by asset.id" ng-click="$ctrl.loadDetail(asset)">
<span class="search-status" style="border-left-color:{{asset.statusColor}};"></span>
<p >{{asset.name}} </p>
<label hide-xs ng-if="asset.disabled" class="ng-animate-disabled">
<md-chips >
<md-chip >{{'LABELS.DISABLED' | translate}}</md-chip>
</md-chips>
</label>
<label ><i>{{asset.status || 'UNKNOWN'}}</i></label>
<md-button aria-label="Delete Asset" class="md-icon-button md-warn" layout-padding ng-click="$ctrl.deleteAsset(asset)">
<md-icon md-svg-icon="delete" class="modelTrashIcon"></md-icon>
</md-button>
<md-divider></md-divider>
</md-list-item>
</md-list>
</md-virtual-repeat-container>
正如你所说,"Angular 1.5 filter with ng-repeat not working by track by id"
我使用 AngularJs 1.5
创建了示例示例,并在 ng-repeat
上使用了带跟踪依据的过滤器。
angular.module('controllerAsExample', [])
.controller('SettingsController1', SettingsController1);
function SettingsController1() {
this.infiniteAssets = [
{disabled :false, name:'test0',id:234 },
{disabled :true, name:'test1',id:123 },
{disabled :false, name:'test2',id:345 }
];
//console.log(this.infiniteAssets);
}
<!doctype html>
<html >
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
</head>
<body ng-app="controllerAsExample">
<div ng-controller="SettingsController1 as settings">
<p>ng-repeat with track by field example using angularjs 1.5.0:</p>
<ul>
<li ng-repeat="asset in settings.infiniteAssets | filter: {disabled: false } track by asset.id">
{{asset.name}}
</li>
</ul>
</div>
</body>
</html>
您确定 md-virtual-repeat
可以使用过滤器吗? AngularJS Materials virtual repeat 是 ng-repeat 的自定义实现,因此您不能指望它能像原来一样工作。这是文档中的内容。
Virtual repeat is a limited substitute for ng-repeat that renders only enough DOM nodes to fill the container and recycling them as the user scrolls.
Arrays, but not objects are supported for iteration. Track by, as alias, and (key, value) syntax are not supported.
我会改为将过滤器移到您的控制器中,并确保在集合发生变化时重新应用过滤器。