programing

AngularJS: ng-repeat을 사용하는 명령어의 요소에 링크

elecom 2023. 10. 5. 21:11
반응형

AngularJS: ng-repeat을 사용하는 명령어의 요소에 링크

템플릿이 ng-repeat을 사용하는 간단한 지시사항이 있습니다.ng-repeat 명령에 의해 생성된 일부 요소에 대해 jquery 구성 요소를 인스턴스화하기 위해 코드를 실행해야 합니다.문제는 이 코드를 링크 기능에 넣으면 됩니다.ng-repeat은 아직 그런 요소들을 만들지 않았기 때문에 인스턴스화된 것은 없습니다.

App.directive('myDirective', ['$compile', '$timeout', function($compile, $timeout) {
  return {
    scope: {
        domains: '='
    },
    templateUrl: '/app/partials/my_directive.html',
    link: function($scope, element, attributes) {
        element.find('.standard-help').tooltip('destroy');
        element.find('.standard-help').tooltip({placement: 'top', trigger: 'click hover focus'});
    }
  };
}

템플릿은 다음과 같이 나타납니다.부착하려고 합니다.

<ul class="media-list domainList">
  <li class="media" style="position:relative;" ng-repeat="domain in domains">
    <a class="domainHeader" href="javascript://">
        <span class="domainHeader">{{domain.tag}}</span>
    </a>
    <div class="media-body" style="margin-left: 52px;">
        <ul class="standardsList">
            <li ng-class="{ standardDisplayed: lessonLayout == 'standards' }" ng-hide="standard.lessons.length == 0" ng-repeat="standard in domain.standards">
                <a href="javascript://" title="{{standard.description}}" ng-show="lessonLayout == 'standards'" class="standard-help pull-right"><i class="icon-question-sign"></i></a>
                <h6 ng-show="lessonLayout == 'standards'">{{standard.tag}}</h6>
                <ul class="lessonsList">
                    <li ng-class="{ lesson: true }" ng-repeat="lesson in standard.lessons" ng-click="onLessonSelected(lesson)">
                        <i class="icon-lock lesson-locked"></i>
                        <div>{{lesson.title}}</div>
                    </li>
                </ul>
            </li>
        </ul>
    </div>
  </li>
</ul>

도메인이 변경될 때 콜백을 등록하고 툴팁 코드를 인스턴스화하기 위해 $watch()와 $observe()를 사용해 보았습니다.그런데 제 시간에 전화가 안 오는 것 같습니다.제가 뭘 놓쳤는지 아시겠어요?

ng-repeat이 생성되는 요소에 추가한 다른 지시를 생성하면 repeat이 생성되는 각 요소에 대해 통지된다는 것을 발견했습니다.그러면 부모 지시에 따라 들을 수 있는 이벤트를 $emit할 수 있습니다.그 지점에서 반복되는 요소에 대한 연결을 수행할 수 있습니다.이것은 특히 돔 내의 여러 ng-repeat에 대해 꽤 잘 작동했습니다. 왜냐하면 새로운 지침에 전달될 이벤트 유형별로 분리할 수 있었기 때문입니다.

제 지시는 이렇습니다.

App.directive("onRepeatDone", function() {
    return {
        restrict: 'A',
        link: function($scope, element, attributes ) {
            $scope.$emit(attributes["onRepeatDone"] || "repeat_done", element);
        }
    }
});

템플릿에서 새 지시어를 사용하는 방법은 다음과 같습니다.

<ul>
    <li on-repeat-done="domain_done" ng-repeat="domain in domains">...</li>
</ul>

그러면 부모 지시문 안에서 다음과 같은 작업을 수행할 수 있습니다.

link: function( $scope, element, attributes ) {
    $scope.$on('domain_done', function( domainElement ) {
        domainElement.find('.someElementInsideARepeatedElement').click(...);
    } );
}

$watch원하는 작업을 수행할 수 있어야 합니다.

link: function(scope, elem, attrs) {
    var init = function() {
        // your initialization code
    };
    var ulElem = elem.children()[0]; // ul element

    var unreg = scope.$watch(function() {
        return ulElem.children.length === scope.domains.length; // check if all "li" are generated
    }, function() {
        // at this point, the ul is rendered
        init();
        unreg(); // unregister the watcher for performance, since the init function only need to be called once
    });
}

이 솔루션을 시연하기 위해 플랭크를 만들었습니다.

저는 이 정확한 문제를 우연히 발견했고 더 나은 해결책이라고 생각하는 것을 발견했습니다.기본적으로 사용할 수 있습니다.$timeoutng-repeat렌더링을 마쳤습니다.

참고:의 시간 지연을 것을 하지 않습니다. 이것은 입니다.입니다.$digest

아래는 제 코드를 발췌한 것입니다.을 사용합니다.ng-repeat.tabSelected()합니다를 .activeHTML 요소에 클래스를 지정합니다.

link($scope:ng.IScope, element:JQuery, attributes:ng.IAttributes):void {
  if (this.autoActivateFirstTab && this.tabs && this.tabs.length > 0) {
    var self = this;

    var selectFirstTab = function() {
      self.tabSelected(self.tabs[0]);
    };

    // Add a $timeout task to the end of the $digest loop to select the
    // first tab after the loop finishes
    self.$timeout(selectFirstTab, 0);
  }
}

http://blog.brunoscopelliti.com/run-a-directive-after-the-dom-has-finished-rendering 에서 솔루션을 찾았습니다. 이 솔루션은 실제 사용 중인 것을 보여주는 라이브 데모가 있습니다.

이별의 단어:카르마를 사용하여 코드를 테스트하는 경우(필요한 경우), 전화를 해야 합니다.$timeout.flush()실행 여부를 확인하기 위한 테스트.

결국 제대로 작동하기 위해 테스트 내에서 다음을 실행해야 했습니다.

// Re-digest to ensure we see the changes
scope.$digest();

// Flush any pending $timeout tasks to ensure we see changes
try {
  this.$timeout.verifyNoPendingTasks();
} catch ( aException ) {
  this.$timeout.flush();
}

이게 각진 벌레 때문인 것 같아요.여기서 보실 수 있습니다.

한 가지 해결 방법은 템플릿 URL을 제거하고 지시문 자체에서 템플릿을 사용하거나 $templateCache.get('/app/partials/my_directive.html')을 사용하는 것입니다.

이거 나한테 통했어요 :)

$watch이런 맥락에서 작동해야 합니다.먹어봐.

언급URL : https://stackoverflow.com/questions/17643681/angularjs-linking-to-elements-in-a-directive-that-uses-ng-repeat

반응형