Javascript 如何将$scope变量传递到自定义指令的字符串模板中? 问题 我有一个用ng repeat构建的项目列表 每个项目都有一个带有“编辑/删除项目”链接的上下文菜单 上下文菜单是使用自定义的下拉列表指令构建的,这些指令来自对象数组,如{title:“Link title”,href:“/some href”}
我需要将Javascript 如何将$scope变量传递到自定义指令的字符串模板中? 问题 我有一个用ng repeat构建的项目列表 每个项目都有一个带有“编辑/删除项目”链接的上下文菜单 上下文菜单是使用自定义的下拉列表指令构建的,这些指令来自对象数组,如{title:“Link title”,href:“/some href”},javascript,angularjs,angularjs-directive,angularjs-ng-repeat,Javascript,Angularjs,Angularjs Directive,Angularjs Ng Repeat,我需要将ng href(project.id)的动态参数传递到指令的模板中,我在ng repeat中使用该模板。我怎样才能做到这一点 这是我的一般性问题。我觉得我对Angular JS的概念有很大的误解,并指望你的帮助 我试过的 我尝试将字符串数组传递到我的指令中,得到的未解析href如下: /projects/%7B%7B%20project.id%20%7D%7D/edit 为什么呢 projects-template.html 我也试过了 传递一个返回已解析字符串数组的函数,但得到一个无
ng href
(project.id
)的动态参数传递到指令的模板中,我在ng repeat
中使用该模板。我怎样才能做到这一点
这是我的一般性问题。我觉得我对Angular JS的概念有很大的误解,并指望你的帮助
我试过的
我尝试将字符串数组传递到我的指令中,得到的未解析href如下:
/projects/%7B%7B%20project.id%20%7D%7D/edit
为什么呢
projects-template.html
我也试过了
传递一个返回已解析字符串数组的函数,但得到一个无休止的递归错误:
10 $digest() iterations reached. Aborting!
为什么
projects-template.html
下拉指令代码
angular.module(“ngDropdowns”,[])指令(“dropdownList”[
“$compile”,“$document”,函数($compile,$document){
var模板;
模板=
“”+
“- ”+
" "+
“
”;
返回{
限制:“A”,
替换:false,
范围:{
下拉列表:“=”,
下拉模式:“=”
},
控制器:[
“$scope”、“$element”、“$attrs”、函数($scope、$element、$attrs){
var$template,$wrap;
$template=angular.element(模板);
$template.data(“$dropdownListController”,此项);
$element.addClass(“选择的下拉菜单”).wrap(“”);
$wrap=$element.parent();
$wrap.append($compile($template)($scope));
$scope.itemSelect=函数(dropdownItem){
如果(dropdownItem.href){
返回;
}
copy(dropdownItem,$scope.dropdownModel);
$wrap.removeClass(“下拉菜单”处于活动状态);
};
$document.find(“body”)。在(“单击”,函数()上){
$wrap.removeClass(“下拉菜单”处于活动状态);
});
$element.on(“单击”),函数(事件){
event.stopPropagation();
$wrap.toggleClass(“下拉菜单”处于活动状态);
});
$wrap.on(“单击”),函数(事件){
event.stopPropagation();
});
}
]
};
}
])
第二种方法更正确,因为您需要根据上下文构造不同的URL。但正如你所看到的,你进入了一个无止境的消化循环
这是因为您每次都返回不同的数组引用
Angular认为它是不同的,所以需要再次转动曲柄,再次调用函数,返回一个新数组,等等
projectGetContextMenu
函数需要缓存结果,并返回相同的引用。像这样:
var contextMenus = {};
$scope.projectGetContextMenu = function(projectID){
if(!contextMenus[projectId]) {
contextMenus[projectId] = [
{
text: "Edit",
href: "/projects/" + projectID + "/edit"
}, {
text: "Delete",
href: "/projects/" + projectID + "/delete"
}
];
}
return contextMenus[projectId];
};
工作如预期,非常感谢快速解决方案!请你也给我一个关于第一种方法的一般提示好吗?如何将表达式传递到指令的模板中?即使在这种特殊情况下,也不是这样,而是一般情况下。或者这不是一种情况,而是一种误解?第一种解决方案不起作用,因为每个项目需要不同的菜单。另一种方法是直接将菜单添加到项目中,然后只引用
project.menus
10 $digest() iterations reached. Aborting!
<li ng-repeat="project in data.projects">
<a ng-href="/projects/{{ project.id }}">{{ project.title }}</a>
<a dropdown-list="projectGetContextMenu(project.id)"></a>
$scope.projectGetContextMenu = function(projectID){
return [
{
text: "Edit",
href: "/projects/" + projectID + "/edit"
}, {
text: "Delete",
href: "/projects/" + projectID + "/delete"
}
];
}
angular.module("ngDropdowns", []).directive("dropdownList", [
"$compile", "$document", function($compile, $document) {
var template;
template =
"<ul>"+
" <li ng-repeat='dropdownItem in dropdownList' ng-class='{ \"active\": dropdownModel && dropdownModel.value == dropdownItem.value }'>"+
" <a href='' ng-href='{{ dropdownItem.href }}' ng-click='itemSelect(dropdownItem)'>{{ dropdownItem.text }}</a>"+
"</ul>";
return {
restrict: "A",
replace: false,
scope: {
dropdownList: "=",
dropdownModel: "="
},
controller: [
"$scope", "$element", "$attrs", function($scope, $element, $attrs) {
var $template, $wrap;
$template = angular.element(template);
$template.data("$dropdownListController", this);
$element.addClass("dropdown_selected").wrap("<div></div>");
$wrap = $element.parent();
$wrap.append($compile($template)($scope));
$scope.itemSelect = function(dropdownItem) {
if (dropdownItem.href) {
return;
}
angular.copy(dropdownItem, $scope.dropdownModel);
$wrap.removeClass("dropdown__active");
};
$document.find("body").on("click", function() {
$wrap.removeClass("dropdown__active");
});
$element.on("click", function(event) {
event.stopPropagation();
$wrap.toggleClass("dropdown__active");
});
$wrap.on("click", function(event) {
event.stopPropagation();
});
}
]
};
}
])
var contextMenus = {};
$scope.projectGetContextMenu = function(projectID){
if(!contextMenus[projectId]) {
contextMenus[projectId] = [
{
text: "Edit",
href: "/projects/" + projectID + "/edit"
}, {
text: "Delete",
href: "/projects/" + projectID + "/delete"
}
];
}
return contextMenus[projectId];
};