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 prioritytí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-thingstrong 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: truevà 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:truevà 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ề ngRepeatmã nguồn: https://github.com/angular/angular.js/blob/master/src/ng/directive/ngRepeat.js
RangeError: Maximum call stack size exceededvì nó cứ được biên dịch mãi mãi.