簡體   English   中英

AngularJS - 指令事件和 DOM 渲染

[英]AngularJS - Directive events and DOM rendering

在下面的代碼中,我試圖使用一個模板(帶有{{ value }}替換),但我已經嘗試了兩天來找到一種獲取呈現代碼以在其上設置一些屬性的方法。

我不能使用樣式選擇器(工作正常),我需要使用 div 的 id。 在我的實際代碼中,我使用了templateUrl: ,而不是內聯代碼,但它具有相同的結果。

我應該收聽哪個事件? 選擇器將在什么時間點起作用? 我已經閱讀了有關編譯和鏈接的內容,並認為答案就在某個地方?

提前致謝...

<!doctype html>
<html lang="en" ng-app="myApp">
   <head>
      <meta charset="utf-8">
      <title>My AngularJS App</title>
      <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
   </head>
   <body style="height:100%; width: 100%;">
      <tls-window window-id="fred" window-width="600" window-label-width="150"></tls-window>
      <script src="lib/angular/angular.js"></script>
      <script src="js/app.js"></script>
      <script src="js/core/services.js"></script>
      <script src="js/core/controllers.js"></script>
      <script src="js/core/filters.js"></script>
      <script src="js/core/directives.js"></script>
      <script src="js/core/tlscore-directives.js"></script>
      <script type="text/javascript">

      var coreDirectives = angular.module('tlsCore.directives', []);
      coreDirectives.directive('tlsWindow', function() {
        return {
          restrict: 'E',
          scope: {
            windowId: '@windowId',
            windowWidth: '@windowWidth',
            labelWidth: '@windowLabelWidth'
          },
          replace: true,
          transclude: false,
          template: '<div id="{{windowId}}" class="tls-window" ng-cloak tls-draggable >' +
            '<div id="{{windowId}}-winBackground" class="tls-window-background" style="width: 300px; height: 200px" >' +
            '<div id="{{windowId}}-winToolbarBackground" class="tls-window-toolbar-background">' +
            '<div id="{{windowId}}-winToolbarContent" class="tls-window-toolbar-content" style="width: 300px; height: 100px">' +
            '</div>' +
            '</div>' +
            '</div>',
          link: function(scope, element, attrs) {
            var ele = element.get(element.index(scope.windowId));
            // this works and sets the colour (by class)
            $('.tls-window-toolbar-content').css("background-color", 'red');
            // this does not work as the id of the element is not yet substituted and rendered ??
            $('#fred-winBackground').css("background-color", 'green');
          }
        }
      });   

      </script>
   </body>
</html>

選項 1 - 更好

不要使用template方法,而是將 HTML 移動到link方法中。 這使我們能夠在編譯之前手動$interpolate括號內的術語,然后使用 ID 選擇器。 請注意,這不會不使用有可能=代替@分離范圍結合,因為@綁定推遲到后面,並在是不確定的link方法(更多的見這里)。

app.directive('tlsWindow', function($interpolate,$compile) {
  return {
    restrict: 'E',
    scope: {
        windowId: '=',
        windowWidth: '=',
        labelWidth: '='
    },
    link: function (scope, element, attrs) {
        var template = '<div id="{{windowId}}" class="tls-window" ng-cloak tls-draggable >' +
        '<div id="{{windowId}}-winBackground" class="tls-window-background" style="width: 300px; height: 200px" >' +
            '<div id="{{windowId}}-winToolbarBackground" class="tls-window-toolbar-background">' +
                '<div id="{{windowId}}-winToolbarContent" class="tls-window-toolbar-content" style="width: 300px; height: 100px">' +
                '</div>' +
            '</div>' +
        '</div>';

        var interpolated = $interpolate(template)(scope);
        var html = $(interpolated);
        element.replaceWith($compile(html)(scope));
        
        $('.tls-window-toolbar-content').css('background-color', 'red');
        $('#fred-winBackground').css('background-color', 'green');
    }   
  }
}); 

這是一個小提琴


選項 2

不是最強大的解決方案,但這也可以。 在這里,使用$timeout將操作推遲到渲染之后。 這也會導致輕微的延遲。

$timeout(function(){
    $('#fred-winBackground').css("background-color", 'green');
},0);

這也需要將$timeout注入指令中。

我看到你有一個關於為什么在鏈接時 id 不可用的答案,但我可以質疑完全使用 id 選擇器的原因嗎? 獲得指令后,您可以通過鏈接函數中 jqLit​​e/jquery 元素的children方法訪問模板中的頂級 div。 看這個例子:

 angular.module('myApp', []) .directive('tlsWindow', function() { return { restrict: 'E', scope: { windowId: '@windowId', windowWidth: '@windowWidth', labelWidth: '@windowLabelWidth' }, replace: true, transclude: false, template: '<div id="{{windowId}}" class="tls-window" ng-cloak tls-draggable >' + '<div id="{{windowId}}-winBackground" class="tls-window-background" style="width: 300px; height: 200px" >' + '<div id="{{windowId}}-winToolbarBackground" class="tls-window-toolbar-background">' + '<div id="{{windowId}}-winToolbarContent" class="tls-window-toolbar-content" style="width: 300px; height: 100px">' + '</div>' + '</div>' + '</div>', link: function(scope, element, attrs) { // var ele = element.get(element.index(scope.windowId)); // this works and sets the colour (by class) // $('.tls-window-toolbar-content').css("background-color", 'red'); // this does not work as the id of the element is not yet substituted and rendered ?? // $('#fred-winBackground').css("background-color", 'green'); // Use the jqlite or jquery children method to locate the first child of your directive // element (from linkFn) is the element of tls-window and children() gets you access to the <div> container in your template element.children().css("background-color", "green"); } } });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script> <div ng-app="myApp"> <tls-window window-id="fred" window-width="600" window-label-width="150"></tls-window> </div>

angularjs 不鼓勵通過 id 選擇器引用元素。 通過傳遞給鏈接函數的元素上下文來使用 jqLit​​e/jquery 方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM