angularjs ng-click 不适用于动态 html 元素
angularjs ng-click not working on dynamic html elements
出于某种原因,当使用此函数 ('testclickfn') 作为 ng-click 动态元素时,它不会调用该函数。这是 angularjs 文件:
app.controller('testctrl',function($scope){
testfn($scope);
$scope.showelements = function(){
displayTestRows();
}
});
function testfn($scope){
$scope.testclickfn = function(){
alert('testing click fn');
};
}
function displayTestRows(){
for(var i=0; i < 5; i++){
$("#testdiv").append('<p ng-click="testclickfn()">click me</p><br>');
}
}
HTML 调用 angularjs 控制器的页面 'testctrl':
<div id="testdiv" ng-controller="testctrl">
<button ng-click="showelements()">Show dynamic elements</button><br>
</div>
我假设 'click me' 标签是在 angular 加载页面后生成的,它在页面生成后什么都不知道所以 ng-click="testclickfn()" 没有在 angularjs 中注册。
我该如何解决这种情况?
您正在以 angular 不知道的方式创建元素(非常糟糕的做法),但不用担心,您可以让 angular 知道!
将控制器签名更改为
controller('testctrl', function($scope, $compile) {
然后运行手动编译新元素以激活ng-click
指令
$scope.showelements = function(){
displayTestRows();
$compile($("#testdiv").contents())($scope);
}
如果你不知道,必须在你的控制器中使用 jquery 选择器是不好的,你应该使用一个指令和 link
函数来将元素附加到范围(即,什么如果你有多个 testctrl 元素?),但这会让你 运行ning
一般规则是 angular 函数之外不应有任何 JS,并且 DOM 操作,在适当的情况下也应由 angular 处理。
示例 1:功能强大
<div ng-controller="ctrl">
<button ng-click="show('#here')">
create
</button>
<div id="here">
I'll create the clickables here.
</div>
</div>
将控制器用于在许多不同事物之间共享内容的事物
.controller('ctrl', ['$scope', '$compile', function($scope, $compile) {
$scope.sharedVariable = 'I am #';
$scope.show = function(where) {
where = $(where).html('');
//lets create a new directive, and even pass it a parameter!
for (var index = 0; index < 5; ++index)
$('<div>', {'test':index}).appendTo(where);
$compile(where.contents())($scope);
};
}])
对每个都有自己状态的非唯一元素使用指令
.directive('test', function() {
return {
//these too have their own controllers in case there are things they need to share with different things -inside them-
controller : ['$scope', function($scope) {
$scope.test = function() {
//see, no selectors, the scope already knows the element!
$scope.element.text(
//remember that parent controller? Just because we're in another one doesnt mean we lost the first!
$scope.$parent.sharedVariable +
$scope.index
);
}
}],
//no need to do things by hand, specify what each of these look like
template : '<p>click me</p>',
//the whole "angular way" thing. Basically no code should be outside angular functions.
//"how do I reference anything in the DOM, then?"; that's what the `link` is for: give the controller access using `scope`!
link : function(scope, element, attributes) {
//you can assign "ng-click" here, instead of putting it in the template
//not everything in angular has to be HTML
scope.element = $(element).click(scope.test);
//did you know you can accept parameters?
scope.index = Number.parseInt(attributes.test) + 1;
},
//just some set up, I'll let you look them up
replace : true,
restrict : 'A',
scope : {}
};
})
示例 2:简单
但这只是一种非常通用且功能强大的做事方式。这完全取决于您需要做什么。如果这个非常简单的例子确实是你需要做的全部,你可以制作一个非常简单的,几乎所有-html版本:
<div ng-controller="ctrl">
<button ng-click="items = [1, 2, 3, 4, 5]">
create
</button>
<p ng-repeat="item in items" ng-click="test($event)">
<span>click me</span>
<span style="display:none">I am #{{item}}</span>
</p>
</div>
.controller('ctrl', ['$scope', function($scope) {
$scope.test = function($event) {
$($event.currentTarget).children().toggle();
};
}])
出于某种原因,当使用此函数 ('testclickfn') 作为 ng-click 动态元素时,它不会调用该函数。这是 angularjs 文件:
app.controller('testctrl',function($scope){
testfn($scope);
$scope.showelements = function(){
displayTestRows();
}
});
function testfn($scope){
$scope.testclickfn = function(){
alert('testing click fn');
};
}
function displayTestRows(){
for(var i=0; i < 5; i++){
$("#testdiv").append('<p ng-click="testclickfn()">click me</p><br>');
}
}
HTML 调用 angularjs 控制器的页面 'testctrl':
<div id="testdiv" ng-controller="testctrl">
<button ng-click="showelements()">Show dynamic elements</button><br>
</div>
我假设 'click me' 标签是在 angular 加载页面后生成的,它在页面生成后什么都不知道所以 ng-click="testclickfn()" 没有在 angularjs 中注册。
我该如何解决这种情况?
您正在以 angular 不知道的方式创建元素(非常糟糕的做法),但不用担心,您可以让 angular 知道!
将控制器签名更改为
controller('testctrl', function($scope, $compile) {
然后运行手动编译新元素以激活ng-click
指令
$scope.showelements = function(){
displayTestRows();
$compile($("#testdiv").contents())($scope);
}
如果你不知道,必须在你的控制器中使用 jquery 选择器是不好的,你应该使用一个指令和 link
函数来将元素附加到范围(即,什么如果你有多个 testctrl 元素?),但这会让你 运行ning
一般规则是 angular 函数之外不应有任何 JS,并且 DOM 操作,在适当的情况下也应由 angular 处理。
示例 1:功能强大
<div ng-controller="ctrl">
<button ng-click="show('#here')">
create
</button>
<div id="here">
I'll create the clickables here.
</div>
</div>
将控制器用于在许多不同事物之间共享内容的事物
.controller('ctrl', ['$scope', '$compile', function($scope, $compile) {
$scope.sharedVariable = 'I am #';
$scope.show = function(where) {
where = $(where).html('');
//lets create a new directive, and even pass it a parameter!
for (var index = 0; index < 5; ++index)
$('<div>', {'test':index}).appendTo(where);
$compile(where.contents())($scope);
};
}])
对每个都有自己状态的非唯一元素使用指令
.directive('test', function() {
return {
//these too have their own controllers in case there are things they need to share with different things -inside them-
controller : ['$scope', function($scope) {
$scope.test = function() {
//see, no selectors, the scope already knows the element!
$scope.element.text(
//remember that parent controller? Just because we're in another one doesnt mean we lost the first!
$scope.$parent.sharedVariable +
$scope.index
);
}
}],
//no need to do things by hand, specify what each of these look like
template : '<p>click me</p>',
//the whole "angular way" thing. Basically no code should be outside angular functions.
//"how do I reference anything in the DOM, then?"; that's what the `link` is for: give the controller access using `scope`!
link : function(scope, element, attributes) {
//you can assign "ng-click" here, instead of putting it in the template
//not everything in angular has to be HTML
scope.element = $(element).click(scope.test);
//did you know you can accept parameters?
scope.index = Number.parseInt(attributes.test) + 1;
},
//just some set up, I'll let you look them up
replace : true,
restrict : 'A',
scope : {}
};
})
示例 2:简单
但这只是一种非常通用且功能强大的做事方式。这完全取决于您需要做什么。如果这个非常简单的例子确实是你需要做的全部,你可以制作一个非常简单的,几乎所有-html版本:
<div ng-controller="ctrl">
<button ng-click="items = [1, 2, 3, 4, 5]">
create
</button>
<p ng-repeat="item in items" ng-click="test($event)">
<span>click me</span>
<span style="display:none">I am #{{item}}</span>
</p>
</div>
.controller('ctrl', ['$scope', function($scope) {
$scope.test = function($event) {
$($event.currentTarget).children().toggle();
};
}])