简体   繁体   English

用AngularJS操作DOM

[英]Manipulating DOM with AngularJS

Im trying to manipulate my table with angularjs using directives. 我试图使用指令使用angularjs操作我的表。

I want to add a new class to the first td with id=2 like this: 我想将新类添加到id = 2的第一个td中,如下所示:

gameApp.directive('mapActivity', function() {
    return {
        link: function(scope, element, attrs) {
            angular.element('.click#1').addClass('dotted');
        }
    };
});

Im trying to "use" the drictive here: 我试图在这里“使用”指令:

<map-activity>
<table ng-bind-html="safeHtml()">
</table>
</map-activity>

But nothing happens. 但是什么也没发生。 The first TD does not get the class 'dotted'. 第一个TD没有获得“点缀”类。 What do I do wrong? 我做错了什么?

Here is my controller: 这是我的控制器:

var gameApp = angular.module("gameApp", ['ngRoute','ngSanitize']);

gameApp.service('link', function() {
    this.user = false;
});
gameApp.filter('unsafe', function($sce) {
    return function(val) {
        return $sce.trustAsHtml(val);
    };
});

gameApp.directive('mapActivity', function() {
    return {
        priority: 1,
        restrict: 'A',
        link: function(scope, element, attrs) {
            angular.element('.click#1').addClass('dotted');
        }
    };
});
function makeTableFrom(str) {
    var k = 1;
    result = "";

    for(var i = 1; i <= 8; i++) {
        result += '<tr>';

        for(var j = 1; j <= 20; j++) {
            if(str[k] == '#') {
                result += '<td id=' + k + '">#</td>';
            }
            else if(str[k] == '&') {
                result += '<td class="click" val="water" id="' + k + '">&</td>';
            }
            else {
                result += '<td class="click" id="' + k + '"><a href="#"></a></td>';
            }

            k++;
        }
        result += '</tr>';
    }
    return result;
}


gameApp.config(function($routeProvider) {
    $routeProvider

    .when('/', {
            templateUrl : 'partials/firstpage.html',
            controller  : 'firstPageCtrl'
    })

    .when('/game', {
            templateUrl : 'partials/game.html',
            controller  : 'gameCtrl'
    });

});

gameApp.controller("firstPageCtrl", function($scope,$http,link,$location) {
    $scope.doLogin = function() {
        $http.post("lib/action.php", {username: $scope.username, password: $scope.password}).success(function(data) {
            if(data) {
                link.user = data;
                console.log(link.user);
                $location.path("/game");
            }
        }).error(function(data) {
            console.log(data);
        });
    };
});


gameApp.controller("gameCtrl", function($scope,$http,link,$location,$sce) {
    //$scope.trr = [1,2,3,4,5,6,7,8];
    //$scope.tdd = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
    $scope.getMonsters = "1";
    var map;

    $http.post("lib/action.php", {monsters: $scope.getMonsters}).success(function(data) {
        map = data;
        console.log(map);
        $scope.result = makeTableFrom(data);
        console.log($scope.result);
    });

    $scope.safeHtml = function() {
        return $sce.trustAsHtml($scope.result);
    };
    if(link.user) {
        /*$scope.message = "fisk";
        console.log(link.user);*/
    } else {
        /*$scope.message = "Ledsen fisk";
        console.log("Är inte satt");*/
    }

});

As you can see, Im using a javascript function to assaign a variable witht the HTML, and then using this in my view, passing it through a filter. 如您所见,Im使用javascript函数来确定HTML变量,然后在我的视图中使用它,将其通过过滤器。

When I hit Ctrl+u to view the source of the page, I can't see the td's and tr's that is being printed out. 当我按Ctrl + u查看页面源时,看不到正在打印的td和tr。 Can this affect why it's not working? 这会影响为什么它不起作用吗?

Try assigning different priority to map-activity directive, so it would process after ng-bind-html 尝试为map-activity指令分配不同的priority ,因此它将在ng-bind-html

And as both @Abhishek Jain and @Dalorzo pointed out , your directive has to be attribute applied to the same DOM element 正如@Abhishek Jain和@Dalorzo所指出的那样,您的指令必须属性应用于相同的DOM元素

.directive('mapActivity', function() {
    return {
       priority: 0,   // check what priority ng-bind-html have and set it to be more than that.
       link: function(scope, element, attrs) {
          ...
       }
    }
})

priority 优先

When there are multiple directives defined on a single DOM element, sometimes it is necessary to specify the order in which the directives are applied. 当在单个DOM元素上定义了多个指令时,有时有必要指定指令的应用顺序。 The priority is used to sort the directives before their compile functions get called. 优先级用于在调用指令的编译函数之前对它们进行排序。 Priority is defined as a number. 优先级定义为数字。 Directives with greater numerical priority are compiled first. 首先编译具有更高数字优先级的指令。 Pre-link functions are also run in priority order, but post-link functions are run in reverse order. 链接前功能也按优先级顺序运行,但链接后功能则以相反顺序运行。 The order of directives with the same priority is undefined. 具有相同优先级的指令的顺序是不确定的。 The default priority is 0. 默认优先级为0。

You need to add the directive to the tag you want to attach it to. 您需要将该指令添加到要附加到其的标签中。 In your directive declaration, you have declared myDirective as an attribute directive, but you are using it as an element directive in your html. 在指令声明中,您已将myDirective声明为属性指令,但在html中将其用作元素指令。

Assuming .click#1 selector corresponds to the first td and you want the directive to be an attribute, you need to do this:- 假设.click#1选择器对应于第一个td,并且您希望该指令为属性,则需要执行以下操作:

<table ng-bind-html="safeHtml()" map-activity>

Edit:- 编辑:-

If you want to target first td of every row, You can just define your directive like this:- 如果要定位每行的第一个td,则只需定义如下指令即可:

app.directive('mapActivity', [function(){
   return {
        restrict: 'A',
        link: function($scope, iElm, iAttrs, controller) {
            iElm.find('tr td:first-of-type').addClass('dotted');
        }
    };
}]);

What you are doing it is a bit odd since what you are doing is creating a new element instead of modifying your current table element with an attribute, like: 您正在执行的操作有点奇怪,因为您正在执行的操作是创建一个新元素,而不是使用属性修改当前表元素,例如:

<table ng-bind-html="safeHtml()" map-Activity="">
</table>

Then: 然后:

gameApp.directive('mapActivity', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
           scope.$watch(attr.ngBindHtml, function(value) {
              angular.element('.click#1').addClass('dotted');                              
           });
        }
    };
});

Additionally make sure you specify to what type of directive is using the restrict attribute A= Attribute, E= Element, C= Class,... Those can be combined restrict: 'EAC', 此外,请确保您使用限制属性指定要使用哪种类型的指令A =属性,E =元素,C =类等...这些可以组合使用restrict: 'EAC',

The link function in your sample version will be executed first and additionally some browsers will have difficulties understanding unknown elements it is because of this that it may be better to move at table level your directive. 您的示例版本中的link函数将首先执行,此外,某些浏览器在理解未知元素方面会遇到困难,因此,最好在表级移动指令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM