Trong trường hợp bạn có nhiều lệnh trên một thành phần DOM duy nhất và khi thứ tự chúng được áp dụng có vấn đề, bạn có thể sử dụng thuộc priority
tính để đặt hàng ứng dụng của chúng. Số cao hơn chạy đầu tiên. Ưu tiên mặc định là 0 nếu bạn không chỉ định một.
EDIT : sau khi thảo luận, đây là giải pháp làm việc hoàn chỉnh. Chìa khóa là loại bỏ thuộc tính : element.removeAttr("common-things");
và cũng element.removeAttr("data-common-things");
(trong trường hợp người dùng chỉ định data-common-things
trong html)
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true, //this setting is important, see explanation below
priority: 1000, //this setting is important, see explanation below
compile: function compile(element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html
return {
pre: function preLink(scope, iElement, iAttrs, controller) { },
post: function postLink(scope, iElement, iAttrs, controller) {
$compile(iElement)(scope);
}
};
}
};
});
Plunker làm việc có sẵn tại: http://plnkr.co/edit/Q13bUt?p=preview
Hoặc là:
angular.module('app')
.directive('commonThings', function ($compile) {
return {
restrict: 'A',
replace: false,
terminal: true,
priority: 1000,
link: function link(scope,element, attrs) {
element.attr('tooltip', '{{dt()}}');
element.attr('tooltip-placement', 'bottom');
element.removeAttr("common-things"); //remove the attribute to avoid indefinite loop
element.removeAttr("data-common-things"); //also remove the same attribute with data- prefix in case users specify data-common-things in the html
$compile(element)(scope);
}
};
});
BẢN GIỚI THIỆU
Giải thích tại sao chúng ta phải đặt terminal: true
và priority: 1000
(một số cao):
Khi DOM đã sẵn sàng, angular đi bộ DOM để xác định tất cả các chỉ thị đã đăng ký và biên dịch từng chỉ thị dựa trên việc priority
các chỉ thị này có nằm trên cùng một phần tử hay không . Chúng tôi đặt mức độ ưu tiên của chỉ thị tùy chỉnh của mình thành một số cao để đảm bảo rằng nó sẽ được biên dịch trước và cùng với đó terminal: true
, các chỉ thị khác sẽ bị bỏ qua sau khi lệnh này được biên dịch.
Khi chỉ thị tùy chỉnh của chúng tôi được biên dịch, nó sẽ sửa đổi thành phần bằng cách thêm các lệnh và xóa chính nó và sử dụng dịch vụ $ compile để biên dịch tất cả các lệnh (bao gồm cả các lệnh bị bỏ qua) .
Nếu chúng ta không thiết lập terminal:true
và priority: 1000
, có khả năng một số chỉ thị được biên soạn trước chỉ thị tùy chỉnh của chúng ta. Và khi chỉ thị tùy chỉnh của chúng tôi sử dụng $ compile để biên dịch phần tử => biên dịch lại các lệnh đã được biên dịch. Điều này sẽ gây ra hành vi không thể đoán trước đặc biệt là nếu các chỉ thị được biên soạn trước chỉ thị tùy chỉnh của chúng tôi đã chuyển đổi DOM.
Để biết thêm thông tin về mức độ ưu tiên và thiết bị đầu cuối, hãy xem Làm thế nào để hiểu 'thiết bị đầu cuối' của chỉ thị?
Một ví dụ về một lệnh cũng sửa đổi mẫu là ng-repeat
(ưu tiên = 1000), khi ng-repeat
được biên dịch, ng-repeat
tạo các bản sao của phần tử mẫu trước khi các lệnh khác được áp dụng .
Nhờ nhận xét của @ Izhaki, đây là tài liệu tham khảo về ngRepeat
mã nguồn: https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js
RangeError: Maximum call stack size exceeded
vì nó cứ được biên dịch mãi mãi.