Javascript, angularjs, ng-mouseover 可以动态插入吗?
Javascript, angularjs, can a ng-mouseover be inserted dynamically?
此代码显然不起作用:
var run_div = document.createElement('div');
run_div.className = 'whatever';
run_div.textContent = 'whatever';
run_div.setAttribute('ng-mouseover', 'console.log(\'ei\')');
document.getElementById('main_div').appendChild(run_div);
我想这是因为 ng-mouseover
必须从一开始就在那里,以便 AngularJS 知道 (?)。
是这样吗?有什么办法吗?
(下图:更新 1、更新 2、更新 3)
更新 1:
这段代码在工厂中工作,我从控制器调用工厂方法向它发送 $scope
:
angular.module('whatever').controller('mycontroller',
['$scope', '$q', '$window', '$timeout',
function ($scope, $q, $window, $timeout) {
$scope.myfunction= function() {
myfactory.mymethod($scope);
};
并且工厂在其定义中调用 $compile
:
angular.module('whatever').factory('myfactory',
['$window', '$q', '$compile',
function($window, $q, $compile) {
...
mymethod = function($scope) {
var run_div = document.createElement('div');
run_div.className = 'whatever';
run_div.textContent = 'whatever';
run_div.setAttribute('ng-mouseover', 'console.log(\'ei\')');
document.getElementById('main_div').appendChild(run_div);
}
这不起作用,然后抛出错误:
document.getElementById('main_div').appendChild($compile(run_div)($scope));
document.getElementById('main_div').appendChild($compile(run_div)($scope.new()));
甚至:
var run_div = angular.element(document.createElement('div'));
run_div.addClass('whatever');
run_div.attr('ng-mouseenter', 'console.log(\'ei\'');
document.getElementById('main_div').appendChild($compile(run_div)($scope));
它抱怨附加时参数不是节点。
Uncaught (in promise) TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.(…)
更新 2:
以下代码显示(我认为)当从工厂编译和附加时它不起作用,但当从控制器执行时它起作用(参见答案 2):
http://jsfiddle.net/xsaudasp/1/
更新 3
我看到这必须起作用,如下所示:
您需要先编译 run_div,然后再将其插入 DOM:
只需这样使用 $compile 服务:
document.getElementById('main_div').appendChild($compile(run_div)($scope));
您应该考虑使用指令,但是:不建议在您的控制器中操纵 DOM。
编辑 1:
以这种方式创建一个指令:
.directive('myShinyElement', function() {
return {
restrict: 'E',
scope: {
text: '='
},
template '<div class="whatever" ng-mouseover="mouseOver()">{{text}}</div>',
link: function(scope, element, attrs, tabsCtrl) {
scope.mouseOver = function(){
console.log('mouseover');
}
}
};
});
并在您的 html:
中使用它
<my-shiny-element text="Dataset.analysis[$index].dataset.name"> </my-shiny-element>
首先你需要为你的指令创建新的 $scope 实例,然后使用 $compile 服务来编译给定的 div 范围:
var directiveScope = $scope.$new();
var compiledDirective = $compile(run_div)(directiveScope);
然后你可以把它附加到DOM:
angular.element('#my_dir').append(compiledDriective);
您必须确保 jQuery 在 angular 之前加载,以便 jQuery 选择器可用。
如果你不想使用 jQuery 你可以使用 jqLite 选择器来代替:
angular.element(document.querySelector('#my_dir')).append(compiledDirective)
这是您需要的工作 jsfiddle:jsfiddle
此代码显然不起作用:
var run_div = document.createElement('div');
run_div.className = 'whatever';
run_div.textContent = 'whatever';
run_div.setAttribute('ng-mouseover', 'console.log(\'ei\')');
document.getElementById('main_div').appendChild(run_div);
我想这是因为 ng-mouseover
必须从一开始就在那里,以便 AngularJS 知道 (?)。
是这样吗?有什么办法吗?
(下图:更新 1、更新 2、更新 3)
更新 1:
这段代码在工厂中工作,我从控制器调用工厂方法向它发送 $scope
:
angular.module('whatever').controller('mycontroller',
['$scope', '$q', '$window', '$timeout',
function ($scope, $q, $window, $timeout) {
$scope.myfunction= function() {
myfactory.mymethod($scope);
};
并且工厂在其定义中调用 $compile
:
angular.module('whatever').factory('myfactory',
['$window', '$q', '$compile',
function($window, $q, $compile) {
...
mymethod = function($scope) {
var run_div = document.createElement('div');
run_div.className = 'whatever';
run_div.textContent = 'whatever';
run_div.setAttribute('ng-mouseover', 'console.log(\'ei\')');
document.getElementById('main_div').appendChild(run_div);
}
这不起作用,然后抛出错误:
document.getElementById('main_div').appendChild($compile(run_div)($scope));
document.getElementById('main_div').appendChild($compile(run_div)($scope.new()));
甚至:
var run_div = angular.element(document.createElement('div'));
run_div.addClass('whatever');
run_div.attr('ng-mouseenter', 'console.log(\'ei\'');
document.getElementById('main_div').appendChild($compile(run_div)($scope));
它抱怨附加时参数不是节点。
Uncaught (in promise) TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.(…)
更新 2:
以下代码显示(我认为)当从工厂编译和附加时它不起作用,但当从控制器执行时它起作用(参见答案 2):
http://jsfiddle.net/xsaudasp/1/
更新 3
我看到这必须起作用,如下所示:
您需要先编译 run_div,然后再将其插入 DOM:
只需这样使用 $compile 服务:
document.getElementById('main_div').appendChild($compile(run_div)($scope));
您应该考虑使用指令,但是:不建议在您的控制器中操纵 DOM。
编辑 1:
以这种方式创建一个指令:
.directive('myShinyElement', function() {
return {
restrict: 'E',
scope: {
text: '='
},
template '<div class="whatever" ng-mouseover="mouseOver()">{{text}}</div>',
link: function(scope, element, attrs, tabsCtrl) {
scope.mouseOver = function(){
console.log('mouseover');
}
}
};
});
并在您的 html:
中使用它<my-shiny-element text="Dataset.analysis[$index].dataset.name"> </my-shiny-element>
首先你需要为你的指令创建新的 $scope 实例,然后使用 $compile 服务来编译给定的 div 范围:
var directiveScope = $scope.$new();
var compiledDirective = $compile(run_div)(directiveScope);
然后你可以把它附加到DOM:
angular.element('#my_dir').append(compiledDriective);
您必须确保 jQuery 在 angular 之前加载,以便 jQuery 选择器可用。 如果你不想使用 jQuery 你可以使用 jqLite 选择器来代替:
angular.element(document.querySelector('#my_dir')).append(compiledDirective)
这是您需要的工作 jsfiddle:jsfiddle