【发布时间】:2017-11-16 14:39:31
【问题描述】:
我有一个 AngularJS 应用程序,在其中一个页面上显示了许多小部件。其中一个小部件显示一个表格,其中包含有关应用程序正在监视的系统的信息。该表目前包含两列:“类型”列,显示该行中显示的信息类型;和一个“数据”列,显示保存该信息的变量的值。
可以使用在小部件工具栏上单击“设置”按钮时打开的对话框自定义小部件上显示的信息。该对话框上有“列”和“行”文本输入字段,用于设置要在表中显示的列标题和行。目前,当用户开始在“行”文本输入字段中输入内容时,会显示一个下拉列表,向用户显示可在表格中显示的变量,并且与用户输入的内容相匹配(即当他们继续键入时,可用选项列表将变得更具体)。
当用户在文本输入字段中键入时,用于向用户显示此下拉菜单的函数是:
$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;
};
我目前正在尝试向该表添加第三列,以显示指向用户将选择的给定页面的链接。我决定用一个以字符: 开头的字符串来表示“链接”(即,如果用户输入:index,那将是指向该网站主页的链接)。
一旦用户键入:,可用页面的完整列表应显示在“下拉列表”中,并且随着用户继续键入,此列表应根据他们键入的内容进行过滤(和变量名一样)
我已将我的函数更新如下:
$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 子句运行,但可用页面未显示在下拉列表中,我看到显示以下输出通过我的console.log() 语句在控制台中:
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 循环开始
TypeError: 无法读取未定义的属性“startsWith”
问题似乎是我无法引用用户页面对象的 key 属性/属性以将它们的值与用户在文本框中键入的值匹配。
鉴于我可以看到我正在使用的 page 对象有一个属性 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 循环开始
TypeError: page.getAttribute 不是函数
大家有什么建议吗?
编辑
我尝试按照@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;
}
});
但是这些都在控制台中给出了相同的输出,即:
使用 foreach 进行迭代
ctrl.js:483 找到匹配页面:pages/userpage2
ctrl.js:483 找到匹配页面:pages/userpage1
ctrl.js:483 找到匹配页面:pages/
ctrl.js:483 找到匹配页面:pages/pagetitle
ctrl.js:483 找到匹配页面: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.forEach is not a function来自ng-tags-input.min.js。 tags 输入指令期望从此函数返回一个字符串数组。您的else块返回一个字符串数组。您的if块应该将字符串数组存储为result。 -
例如
var result = [];和if(page.key.startsWith(buttonsQuery)) { result.push(page.key); }
标签: javascript angularjs foreach filter getattribute