AngularJS- 如何按 object 的 属性/ 属性进行过滤 - forEach 不是函数
AngularJS- How to filter by property/ attribute of an object- forEach is not a function
我有一个 AngularJS 应用程序,在其中一个页面上显示了许多小部件。其中一个小部件显示 table,其中包含有关应用程序正在监视的系统的信息。此 table 当前包含两列: 'Type' 列,显示该行中显示的信息类型;和一个 'Data' 列,显示保存该信息的变量的值。
可以使用在窗口小部件工具栏上单击 'Settings' 按钮时打开的对话框来自定义窗口小部件上显示的信息。该对话框上有 'Columns' 和 'Rows' 文本输入字段,用于设置要在 table 中显示的列标题和行。当前,当用户开始在 'Rows' 文本输入字段中键入内容时,会显示一个下拉列表,向用户显示可在 table 中显示的变量,这些变量与用户所拥有的相匹配键入(即,当他们继续键入时,可用选项列表将变得更加具体)。
用于在用户在文本输入字段中键入时向其显示此下拉菜单的函数是:
$scope.autocompleteVarsFilter = function(query) {
if(!query && lastVarQryKw) {
query = lastVarQryKw;
}
var result = Object.keys(fxVar.getVars()).filter(function(name) {
return name.indexOf(query.toLowerCase()) !== -1;
});
if(result.length > 0) {
lastVarQryKw = query;
}
return result;
};
我目前正在尝试向 table 添加第三列,以在用户将选择的给定页面上显示 link。我决定 'link' 将由以字符 :
开头的字符串表示(即,如果用户输入 :index
,那将是主页的 link网站)。
一旦用户键入 :
,可用页面的完整列表应显示在 'drop-down' 中,并且随着用户继续键入,此列表应根据什么进行过滤他们正在输入(就像变量名一样)
我已经更新了我的函数如下:
$scope.autocompleteVarsFilter = function(query) {
if(query.startWith(":") {
var buttonsQuery = query.substring(1);
if(!buttonsQuery && lastVarQryKw) {
buttonsQuery = lastVarQryKw;
}
var userPages = pagesPresets; //This is getting the full list of available pages from a service called 'pagesPresets'
console.log("Value of userPages: ", userPages);
var page;
for(page in userPages) {
console.log("for loop started");
if(page.key.startWith(buttonsQuery)) {
console.log("Matching page found: ", page);
}
}
if(result.length > 0) {
lastVarQryKw = query;
}
return result;
} else {
if(!query && lastVarQryKw) {
query = lastVarQryKw;
}
var result = Object.keys(fxVar.getVars()).filter(function(name) {
return name.indexOf(query.toLowerCase()) !== -1;
});
if(result.length > 0) {
lastVarQryKw = query;
}
return result;
}
};
if
语句的 else
子句执行函数最初执行的操作(即显示可用变量),目前仍按预期工作。但是,在测试此功能时,如果我现在在文本输入字段中键入 :
后跟任何字符串,if
子句 运行s,但可用页面不会显示在下拉列表中下来,我看到 console.log()
语句在控制台中显示以下输出:
Value of userPages:
0: {_id: "...", _rev: 1, _url: "...", key: "pages/auth", {...}, ...}
1: {_id: "...", _rev: 13, _url: "...", key: "pages/userpage2", value: {...}, ...}
2: {_id: "...", _rev:13, _url: "...", key: "pages/", value: "/pages/userpage1", ...}
for loop started
TypeError: 无法读取未定义的 属性 'startsWith'
问题似乎是我无法引用用户页面 objects 的 key
属性/ 属性 来将它们的值与用户输入的值相匹配文本框。
鉴于我可以看到我正在使用的 page
objects 有一个属性 key
包含我要过滤的值,我如何实际掌握要使用这个 key
属性吗?
我尝试将 for
循环更改为:
var page;
var key;
for(page in userPages) {
console.log("for loop started");
key = page.getAttribute("key");
if(key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page);
}
}
但这只是给出了输出:
for loop started
TypeError: page.getAttribute is not a function
有人有什么建议吗?
编辑
我尝试按照@Alex K 在他们的回答中的建议进行操作,并将函数中的 for
循环更新为:
var page;
var pageKey;
var key;
var result;
console.log("Iterating using foreach");
for(page in userPages) {
page = userPages[page];
if(page.key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page.key);
pageKey = page.key;
result = pageKey;
}
};
我也尝试将其更新为:
userPages.forEach(function(page) {
page = userPages[page];
if(page.key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page.key);
pageKey = page.key;
result = pageKey;
}
});
和:
userPages.forEach(function(page) {
page = userPages[page];
if(page.key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page.key);
pageKey = page.key;
result = pageKey;
}
});
但是这些都在控制台中给出了相同的输出,即:
Iterating using foreach
ctrl.js:483 Matching page found: pages/userpage2
ctrl.js:483 Matching page found: pages/userpage1
ctrl.js:483 Matching page found: pages/
ctrl.js:483 Matching page found: pages/pagetitle
ctrl.js:483 Matching page found: pages/auth
angular.js:10160 TypeError: a.forEach is not a function
at Object.b.makeObjectArray (ng-tags-input.min.js:1)
at ng-tags-input.min.js:1
at wrappedCallback (angular.js:11735)
at wrappedCallback (angular.js:11735)
at angular.js:11821
at Scope.$eval (angular.js:12864)
at Scope.$digest (angular.js:12676)
at Scope.$apply (angular.js:12968)
at angular.js:14494
at completeOutstandingRequest (angular.js:4413)
很明显,if
语句中的行是 运行,因为我在控制台中获取了所有这些打印语句,但出于某种原因,它认为 forEach
不是函数...
有人对如何解决这个问题有任何建议吗?
A for...in
loop 遍历 object 的可枚举 属性 names。然后您需要使用该 属性 名称访问该对象以获取该值。这是一个例子:
console.log('Using for...in on an object:');
var myObj = {
'prop1': 'Hello world!',
'prop2': 12345,
'some crazy property': null
};
for (var propName in myObj) {
console.log('propName is ' + propName);
//Now we can lookup the value using that property name.
var propValue = myObj[propName];
console.log('myObj[' + propName + '] is ' + propValue);
}
相比之下,forEach
loop 直接遍历 数组 的 值 。你的回调函数直接提供了值,所以你不需要访问数组来检索它。示例:
console.log('Using forEach on an array:');
var myArray = [
{key: 'this is object 1!'},
{key: 'this is object 2!'}
];
myArray.forEach(function (obj) {
console.log('in ForEach loop...');
console.log('obj is ' + JSON.stringify(obj));
//We can directly access the object's properties as needed
console.log('obj.key is ' + obj.key);
});
因此,以下是使用 for...in
或使用 forEach
更新代码的方法:
var buttonsQuery = 'pages/userpage2';
var userPages = [{
_id: "...",
_rev: 1,
_url: "...",
key: "pages/auth"
},
{
_id: "...",
_rev: 13,
_url: "...",
key: "pages/userpage2"
},
{
_id: "...",
_rev: 13,
_url: "...",
key: "pages/",
value: "/pages/userpage1"
}
]
console.log('Iterating using for...in');
for (var prop in userPages) {
console.log('prop is ' + prop);
//Access the page object using the property name
var page = userPages[prop];
console.log('page is ' + JSON.stringify(page));
if (page.key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page);
}
}
//Better way to iterate if userPages is an array:
console.log('iterating using forEach');
userPages.forEach(function(page) {
//page is already the object we're interested in.
//No need to access the array again.
console.log('page is ' + JSON.stringify(page));
//Access the object's properties as needed
if (page.key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page);
}
});
您也可以使用 for...of loop
进行迭代,但 IE 不支持。
我有一个 AngularJS 应用程序,在其中一个页面上显示了许多小部件。其中一个小部件显示 table,其中包含有关应用程序正在监视的系统的信息。此 table 当前包含两列: 'Type' 列,显示该行中显示的信息类型;和一个 'Data' 列,显示保存该信息的变量的值。
可以使用在窗口小部件工具栏上单击 'Settings' 按钮时打开的对话框来自定义窗口小部件上显示的信息。该对话框上有 'Columns' 和 'Rows' 文本输入字段,用于设置要在 table 中显示的列标题和行。当前,当用户开始在 'Rows' 文本输入字段中键入内容时,会显示一个下拉列表,向用户显示可在 table 中显示的变量,这些变量与用户所拥有的相匹配键入(即,当他们继续键入时,可用选项列表将变得更加具体)。
用于在用户在文本输入字段中键入时向其显示此下拉菜单的函数是:
$scope.autocompleteVarsFilter = function(query) {
if(!query && lastVarQryKw) {
query = lastVarQryKw;
}
var result = Object.keys(fxVar.getVars()).filter(function(name) {
return name.indexOf(query.toLowerCase()) !== -1;
});
if(result.length > 0) {
lastVarQryKw = query;
}
return result;
};
我目前正在尝试向 table 添加第三列,以在用户将选择的给定页面上显示 link。我决定 'link' 将由以字符 :
开头的字符串表示(即,如果用户输入 :index
,那将是主页的 link网站)。
一旦用户键入 :
,可用页面的完整列表应显示在 'drop-down' 中,并且随着用户继续键入,此列表应根据什么进行过滤他们正在输入(就像变量名一样)
我已经更新了我的函数如下:
$scope.autocompleteVarsFilter = function(query) {
if(query.startWith(":") {
var buttonsQuery = query.substring(1);
if(!buttonsQuery && lastVarQryKw) {
buttonsQuery = lastVarQryKw;
}
var userPages = pagesPresets; //This is getting the full list of available pages from a service called 'pagesPresets'
console.log("Value of userPages: ", userPages);
var page;
for(page in userPages) {
console.log("for loop started");
if(page.key.startWith(buttonsQuery)) {
console.log("Matching page found: ", page);
}
}
if(result.length > 0) {
lastVarQryKw = query;
}
return result;
} else {
if(!query && lastVarQryKw) {
query = lastVarQryKw;
}
var result = Object.keys(fxVar.getVars()).filter(function(name) {
return name.indexOf(query.toLowerCase()) !== -1;
});
if(result.length > 0) {
lastVarQryKw = query;
}
return result;
}
};
if
语句的 else
子句执行函数最初执行的操作(即显示可用变量),目前仍按预期工作。但是,在测试此功能时,如果我现在在文本输入字段中键入 :
后跟任何字符串,if
子句 运行s,但可用页面不会显示在下拉列表中下来,我看到 console.log()
语句在控制台中显示以下输出:
Value of userPages:
0: {_id: "...", _rev: 1, _url: "...", key: "pages/auth", {...}, ...}
1: {_id: "...", _rev: 13, _url: "...", key: "pages/userpage2", value: {...}, ...}
2: {_id: "...", _rev:13, _url: "...", key: "pages/", value: "/pages/userpage1", ...}
for loop started
TypeError: 无法读取未定义的 属性 'startsWith'
问题似乎是我无法引用用户页面 objects 的 key
属性/ 属性 来将它们的值与用户输入的值相匹配文本框。
鉴于我可以看到我正在使用的 page
objects 有一个属性 key
包含我要过滤的值,我如何实际掌握要使用这个 key
属性吗?
我尝试将 for
循环更改为:
var page;
var key;
for(page in userPages) {
console.log("for loop started");
key = page.getAttribute("key");
if(key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page);
}
}
但这只是给出了输出:
for loop started
TypeError: page.getAttribute is not a function
有人有什么建议吗?
编辑
我尝试按照@Alex K 在他们的回答中的建议进行操作,并将函数中的 for
循环更新为:
var page;
var pageKey;
var key;
var result;
console.log("Iterating using foreach");
for(page in userPages) {
page = userPages[page];
if(page.key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page.key);
pageKey = page.key;
result = pageKey;
}
};
我也尝试将其更新为:
userPages.forEach(function(page) {
page = userPages[page];
if(page.key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page.key);
pageKey = page.key;
result = pageKey;
}
});
和:
userPages.forEach(function(page) {
page = userPages[page];
if(page.key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page.key);
pageKey = page.key;
result = pageKey;
}
});
但是这些都在控制台中给出了相同的输出,即:
Iterating using foreach
ctrl.js:483 Matching page found: pages/userpage2
ctrl.js:483 Matching page found: pages/userpage1
ctrl.js:483 Matching page found: pages/
ctrl.js:483 Matching page found: pages/pagetitle
ctrl.js:483 Matching page found: pages/auth
angular.js:10160 TypeError: a.forEach is not a function
at Object.b.makeObjectArray (ng-tags-input.min.js:1)
at ng-tags-input.min.js:1
at wrappedCallback (angular.js:11735)
at wrappedCallback (angular.js:11735)
at angular.js:11821
at Scope.$eval (angular.js:12864)
at Scope.$digest (angular.js:12676)
at Scope.$apply (angular.js:12968)
at angular.js:14494
at completeOutstandingRequest (angular.js:4413)
很明显,if
语句中的行是 运行,因为我在控制台中获取了所有这些打印语句,但出于某种原因,它认为 forEach
不是函数...
有人对如何解决这个问题有任何建议吗?
A for...in
loop 遍历 object 的可枚举 属性 names。然后您需要使用该 属性 名称访问该对象以获取该值。这是一个例子:
console.log('Using for...in on an object:');
var myObj = {
'prop1': 'Hello world!',
'prop2': 12345,
'some crazy property': null
};
for (var propName in myObj) {
console.log('propName is ' + propName);
//Now we can lookup the value using that property name.
var propValue = myObj[propName];
console.log('myObj[' + propName + '] is ' + propValue);
}
相比之下,forEach
loop 直接遍历 数组 的 值 。你的回调函数直接提供了值,所以你不需要访问数组来检索它。示例:
console.log('Using forEach on an array:');
var myArray = [
{key: 'this is object 1!'},
{key: 'this is object 2!'}
];
myArray.forEach(function (obj) {
console.log('in ForEach loop...');
console.log('obj is ' + JSON.stringify(obj));
//We can directly access the object's properties as needed
console.log('obj.key is ' + obj.key);
});
因此,以下是使用 for...in
或使用 forEach
更新代码的方法:
var buttonsQuery = 'pages/userpage2';
var userPages = [{
_id: "...",
_rev: 1,
_url: "...",
key: "pages/auth"
},
{
_id: "...",
_rev: 13,
_url: "...",
key: "pages/userpage2"
},
{
_id: "...",
_rev: 13,
_url: "...",
key: "pages/",
value: "/pages/userpage1"
}
]
console.log('Iterating using for...in');
for (var prop in userPages) {
console.log('prop is ' + prop);
//Access the page object using the property name
var page = userPages[prop];
console.log('page is ' + JSON.stringify(page));
if (page.key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page);
}
}
//Better way to iterate if userPages is an array:
console.log('iterating using forEach');
userPages.forEach(function(page) {
//page is already the object we're interested in.
//No need to access the array again.
console.log('page is ' + JSON.stringify(page));
//Access the object's properties as needed
if (page.key.startsWith(buttonsQuery)) {
console.log("Matching page found: ", page);
}
});
您也可以使用 for...of loop
进行迭代,但 IE 不支持。